Skip to content

Commit 66a710c

Browse files
authored
Merge pull request #35 from handinugroho/add-startweekon-feature
Add Start Week Day options
2 parents fe2e365 + d16f730 commit 66a710c

File tree

6 files changed

+98
-17
lines changed

6 files changed

+98
-17
lines changed

pages/index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ export default function Playground() {
2323
const [containerClassName, setContainerClassName] = useState("");
2424
const [displayFormat, setDisplayFormat] = useState("YYYY-MM-DD");
2525
const [readOnly, setReadOnly] = useState(false);
26-
const [startFrom, setStartFrom] = useState("2023-01-02");
2726
const [minDate, setMinDate] = useState("");
2827
const [maxDate, setMaxDate] = useState("");
2928
const [disabledDates, setDisabledDates] = useState([]);
3029
const [newDisabledDates, setNewDisabledDates] = useState({ startDate: "", endDate: "" });
30+
const [startFrom, setStartFrom] = useState("2023-03-01");
31+
const [startWeekOn, setStartWeekOn] = useState("");
3132

3233
return (
3334
<div className="px-4 py-8">
@@ -65,6 +66,7 @@ export default function Playground() {
6566
minDate={minDate}
6667
maxDate={maxDate}
6768
disabledDates={disabledDates}
69+
startWeekOn={startWeekOn}
6870
/>
6971
</div>
7072

@@ -227,6 +229,19 @@ export default function Playground() {
227229
}}
228230
/>
229231
</div>
232+
<div className="mb-2">
233+
<label className="block" htmlFor="startWeekOnClassName">
234+
Start Week On
235+
</label>
236+
<input
237+
className="rounded border px-4 py-2 w-full border-gray-200"
238+
id="startWeekOnClassName"
239+
value={startWeekOn}
240+
onChange={e => {
241+
setStartWeekOn(e.target.value);
242+
}}
243+
/>
244+
</div>
230245
</div>
231246
<div className="w-full sm:w-1/3 pr-2 flex flex-col">
232247
<div className="mb-2">

src/components/Calendar/Week.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,51 @@
11
import dayjs from "dayjs";
2+
import weekday from "dayjs/plugin/weekday";
23
import React, { useContext } from "react";
34

45
import DatepickerContext from "../../contexts/DatepickerContext";
56
import { loadLanguageModule, shortString, ucFirst } from "../../helpers";
67

8+
dayjs.extend(weekday);
9+
710
const Week: React.FC = () => {
8-
const { i18n } = useContext(DatepickerContext);
11+
const { i18n, startWeekOn } = useContext(DatepickerContext);
912
loadLanguageModule(i18n);
13+
let startDateModifier = dayjs().locale(i18n).weekday(0).get("day");
14+
if (startWeekOn) {
15+
switch (startWeekOn) {
16+
case "mon":
17+
startDateModifier = 1;
18+
break;
19+
case "tue":
20+
startDateModifier = 2;
21+
break;
22+
case "wed":
23+
startDateModifier = 3;
24+
break;
25+
case "thu":
26+
startDateModifier = 4;
27+
break;
28+
case "fri":
29+
startDateModifier = 5;
30+
break;
31+
case "sat":
32+
startDateModifier = 6;
33+
break;
34+
case "sun":
35+
startDateModifier = 0;
36+
break;
37+
default:
38+
break;
39+
}
40+
}
1041

1142
return (
1243
<div className="grid grid-cols-7 border-b border-gray-300 dark:border-gray-700 py-2">
1344
{[0, 1, 2, 3, 4, 5, 6].map((item, index) => (
1445
<div key={index} className="tracking-wide text-gray-500 text-center">
1546
{ucFirst(
1647
shortString(
17-
dayjs(`2022-11-${6 + item}`)
48+
dayjs(`2022-11-${6 + (item + startDateModifier)}`)
1849
.locale(i18n)
1950
.format("ddd")
2051
)

src/components/Calendar/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,22 @@ const Calendar: React.FC<Props> = ({
5151
changeDatepickerValue,
5252
hideDatepicker,
5353
asSingle,
54-
i18n
54+
i18n,
55+
startWeekOn
5556
} = useContext(DatepickerContext);
5657
loadLanguageModule(i18n);
5758

5859
// States
5960
const [showMonths, setShowMonths] = useState(false);
6061
const [showYears, setShowYears] = useState(false);
6162
const [year, setYear] = useState(date.year());
62-
6363
// Functions
6464
const previous = useCallback(() => {
6565
return getLastDaysInMonth(
6666
previousMonth(date),
67-
getNumberOfDay(getFirstDayInMonth(date).ddd) - 1
67+
getNumberOfDay(getFirstDayInMonth(date).ddd, i18n, startWeekOn)
6868
);
69-
}, [date]);
69+
}, [date, i18n, startWeekOn]);
7070

7171
const current = useCallback(() => {
7272
return getDaysInMonth(formatDate(date));

src/components/Datepicker.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ interface Props {
4646
minDate?: DateType | null;
4747
maxDate?: DateType | null;
4848
disabledDates?: DateRangeType[] | null;
49+
startWeekOn?: string | null;
4950
}
5051

5152
const Datepicker: React.FC<Props> = ({
@@ -68,7 +69,8 @@ const Datepicker: React.FC<Props> = ({
6869
readOnly = false,
6970
minDate = null,
7071
maxDate = null,
71-
disabledDates = null
72+
disabledDates = null,
73+
startWeekOn = "sun"
7274
}) => {
7375
// Ref
7476
const containerRef = useRef<HTMLDivElement>(null);
@@ -281,7 +283,8 @@ const Datepicker: React.FC<Props> = ({
281283
displayFormat,
282284
minDate,
283285
maxDate,
284-
disabledDates
286+
disabledDates,
287+
startWeekOn
285288
};
286289
}, [
287290
asSingle,
@@ -305,7 +308,8 @@ const Datepicker: React.FC<Props> = ({
305308
firstGotoDate,
306309
minDate,
307310
maxDate,
308-
disabledDates
311+
disabledDates,
312+
startWeekOn
309313
]);
310314

311315
return (

src/contexts/DatepickerContext.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface DatepickerStore {
2727
inputClassName?: string | null;
2828
containerClassName?: string | null;
2929
readOnly?: boolean;
30+
startWeekOn?: string | null;
3031
displayFormat?: string;
3132
minDate?: DateType | null;
3233
maxDate?: DateType | null;
@@ -62,7 +63,8 @@ const DatepickerContext = createContext<DatepickerStore>({
6263
displayFormat: "YYYY-MM-DD",
6364
minDate: null,
6465
maxDate: null,
65-
disabledDates: null
66+
disabledDates: null,
67+
startWeekOn: "sun"
6668
});
6769

6870
export default DatepickerContext;

src/helpers/index.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import dayjs from "dayjs";
2+
import weekday from "dayjs/plugin/weekday";
23

3-
export function classNames(...classes: (false | null | undefined | string)[]) {
4-
return classes.filter(Boolean).join(" ");
5-
}
6-
4+
dayjs.extend(weekday);
75
export function getTextColorByPrimaryColor(color: string) {
86
switch (color) {
97
case "blue":
@@ -127,12 +125,43 @@ export function getLastElementsInArray(array: number[] = [], size = 0) {
127125
return result.reverse();
128126
}
129127

130-
export function getNumberOfDay(dayString: string): number {
128+
export function getNumberOfDay(dayString: string, i18n: string, startWeekOn?: string): number {
131129
let number = 0;
130+
131+
let startDateModifier = 7 - dayjs().locale(i18n).weekday(0).get("day");
132+
133+
if (startWeekOn) {
134+
switch (startWeekOn) {
135+
case "mon":
136+
startDateModifier = 6;
137+
break;
138+
case "tue":
139+
startDateModifier = 5;
140+
break;
141+
case "wed":
142+
startDateModifier = 4;
143+
break;
144+
case "thu":
145+
startDateModifier = 3;
146+
break;
147+
case "fri":
148+
startDateModifier = 2;
149+
break;
150+
case "sat":
151+
startDateModifier = 1;
152+
break;
153+
case "sun":
154+
startDateModifier = 0;
155+
break;
156+
default:
157+
break;
158+
}
159+
}
160+
132161
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"].forEach(
133162
(item, index) => {
134163
if (item.includes(dayString)) {
135-
number = index + 1;
164+
number = (index + startDateModifier) % 7;
136165
}
137166
}
138167
);

0 commit comments

Comments
 (0)