Skip to content

Commit 9705bfe

Browse files
committedAug 7, 2024
basic calendar working
1 parent 4a15da4 commit 9705bfe

File tree

8 files changed

+314
-92
lines changed

8 files changed

+314
-92
lines changed
 

‎apps/expo/app.config.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
88
version: "0.1.0",
99
orientation: "portrait",
1010
icon: "./assets/icon.png",
11-
userInterfaceStyle: "light",
11+
userInterfaceStyle: "automatic",
1212
splash: {
1313
image: "./assets/icon.png",
1414
resizeMode: "contain",
@@ -19,6 +19,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
1919
},
2020
assetBundlePatterns: ["**/*"],
2121
ios: {
22+
userInterfaceStyle: "automatic",
2223
bundleIdentifier: "com.projecthyper.app",
2324
supportsTablet: true,
2425
usesAppleSignIn: true,
@@ -27,6 +28,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
2728
},
2829
},
2930
android: {
31+
userInterfaceStyle: "automatic",
3032
package: "com.projecthyper.app",
3133
adaptiveIcon: {
3234
foregroundImage: "./assets/icon.png",
+31-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,43 @@
1+
import { View } from "react-native";
12
import { SafeAreaView } from "react-native-safe-area-context";
23

4+
import { BasicCalendar } from "~/components/calendar";
5+
import { HomeCalendar } from "~/components/home/home-calendar";
36
import { Button } from "~/components/ui/button";
7+
import {
8+
Dialog,
9+
DialogContent,
10+
DialogFooter,
11+
DialogTrigger,
12+
} from "~/components/ui/dialog";
413
import { Text } from "~/components/ui/text";
514

615
export default function HomeScreen() {
716
return (
817
<SafeAreaView>
918
<Text>Home Screen</Text>
10-
<Button />
19+
<Button>
20+
<Text>Today</Text>
21+
</Button>
22+
<Dialog>
23+
<DialogTrigger asChild>
24+
<Button variant="outline">
25+
<Text>Open Calendar</Text>
26+
</Button>
27+
</DialogTrigger>
28+
<DialogContent
29+
className="rounded-none border-0"
30+
overlayClassName="justify-start p-0"
31+
noClose
32+
>
33+
<View className="max-h-80">
34+
<HomeCalendar />
35+
</View>
36+
<DialogFooter className="flex-row-reverse">
37+
<Text>TIR</Text>
38+
</DialogFooter>
39+
</DialogContent>
40+
</Dialog>
1141
</SafeAreaView>
1242
);
1343
}

‎apps/expo/src/app/_layout.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ export default function RootLayout() {
137137
const { colorScheme, setColorScheme, isDarkColorScheme } = useColorScheme();
138138
const [isColorSchemeLoaded, setIsColorSchemeLoaded] = useState(false);
139139

140+
console.log(colorScheme);
141+
140142
useEffect(() => {
141143
(async () => {
142144
const theme = await AsyncStorage.getItem("theme");

‎apps/expo/src/components/calendar.tsx

+91-17
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,98 @@
1-
import { useState } from "react";
2-
import { Text, View } from "react-native";
3-
import { Calendar, toDateId } from "@marceloterreiro/flash-calendar";
1+
import type { CalendarProps } from "@marceloterreiro/flash-calendar";
2+
import { View } from "react-native";
3+
import { Calendar, useCalendar } from "@marceloterreiro/flash-calendar";
44

5-
const today = toDateId(new Date());
5+
import { Button } from "~/components/ui/button";
6+
import { Text } from "~/components/ui/text";
7+
import { ChevronLeft } from "~/lib/icons/chevron-left";
8+
import { ChevronRight } from "~/lib/icons/chevron-right";
9+
10+
const DAY_HEIGHT = 25;
11+
const MONTH_HEADER_HEIGHT = 40;
12+
const WEEK_DAYS_HEIGHT = 25;
13+
const FOOTER_HEIGHT = 30;
14+
15+
const BORDER_WIDTH = 1;
16+
17+
interface BasicCalendarProps extends CalendarProps {
18+
onPreviousMonthPress: () => void;
19+
onNextMonthPress: () => void;
20+
}
21+
22+
export function BasicCalendar(props: BasicCalendarProps) {
23+
const { calendarRowMonth, weekDaysList, weeksList } = useCalendar(props);
624

7-
export function BasicCalendar() {
8-
const [selectedDate, setSelectedDate] = useState(today);
925
return (
1026
<View>
11-
<Text>Selected date: {selectedDate}</Text>
12-
<Calendar
13-
calendarActiveDateRanges={[
14-
{
15-
startId: selectedDate,
16-
endId: selectedDate,
17-
},
18-
]}
19-
calendarMonthId={today}
20-
onCalendarDayPress={setSelectedDate}
21-
/>
27+
<Calendar.VStack spacing={props.calendarRowVerticalSpacing}>
28+
{/* Replaces `Calendar.Row.Month` with a custom implementation */}
29+
<Calendar.HStack
30+
alignItems="center"
31+
justifyContent="space-around"
32+
width="100%"
33+
>
34+
<Button
35+
onPress={props.onPreviousMonthPress}
36+
size={"icon"}
37+
className="bg-transparent active:opacity-50"
38+
>
39+
<ChevronLeft className="text-foreground" size={48} />
40+
</Button>
41+
<Text>{calendarRowMonth.split(" ")[0]?.toUpperCase()}</Text>
42+
<Button
43+
onPress={props.onNextMonthPress}
44+
size={"icon"}
45+
className="bg-transparent active:opacity-50"
46+
>
47+
<ChevronRight className="text-foreground" size={48} />
48+
</Button>
49+
</Calendar.HStack>
50+
51+
<Calendar.Row.Week spacing={4}>
52+
{weekDaysList.map((day, i) => (
53+
<Calendar.Item.WeekName height={WEEK_DAYS_HEIGHT} key={i}>
54+
{day.toUpperCase()}
55+
</Calendar.Item.WeekName>
56+
))}
57+
<View />
58+
</Calendar.Row.Week>
59+
60+
{weeksList.map((week, i) => (
61+
<Calendar.Row.Week key={i}>
62+
{week.map((day) => {
63+
if (day.isDifferentMonth) {
64+
return (
65+
<Calendar.Item.Day.Container
66+
dayHeight={DAY_HEIGHT}
67+
daySpacing={4}
68+
isStartOfWeek={day.isStartOfWeek}
69+
key={day.id}
70+
>
71+
<Calendar.Item.Empty height={DAY_HEIGHT} />
72+
</Calendar.Item.Day.Container>
73+
);
74+
}
75+
76+
return (
77+
<Calendar.Item.Day.Container
78+
dayHeight={DAY_HEIGHT}
79+
daySpacing={4}
80+
isStartOfWeek={day.isStartOfWeek}
81+
key={day.id}
82+
>
83+
<Calendar.Item.Day
84+
height={DAY_HEIGHT}
85+
metadata={day}
86+
onPress={props.onCalendarDayPress}
87+
>
88+
{day.displayLabel}
89+
</Calendar.Item.Day>
90+
</Calendar.Item.Day.Container>
91+
);
92+
})}
93+
</Calendar.Row.Week>
94+
))}
95+
</Calendar.VStack>
2296
</View>
2397
);
2498
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import type {
2+
CalendarActiveDateRange,
3+
CalendarOnDayPress,
4+
} from "@marceloterreiro/flash-calendar";
5+
import { useCallback, useMemo, useState } from "react";
6+
import { View } from "react-native";
7+
import { fromDateId, toDateId } from "@marceloterreiro/flash-calendar";
8+
import { add, sub } from "date-fns";
9+
import { format } from "date-fns/fp";
10+
11+
import { BasicCalendar } from "~/components/calendar";
12+
13+
export function HomeCalendar() {
14+
const [currentCalendarMonth, setCurrentCalendarMonth] = useState(new Date());
15+
const [selectedDate, setSelectedDate] = useState<Date>(
16+
sub(new Date(), { days: 1 }),
17+
);
18+
19+
const handleDayPress = useCallback<CalendarOnDayPress>((dateId) => {
20+
setCurrentCalendarMonth(fromDateId(dateId));
21+
setSelectedDate(fromDateId(dateId));
22+
}, []);
23+
24+
const calendarActiveDateRanges = useMemo<CalendarActiveDateRange[]>(
25+
() => [
26+
{
27+
startId: toDateId(selectedDate),
28+
endId: toDateId(selectedDate),
29+
},
30+
],
31+
[selectedDate],
32+
);
33+
34+
const handlePreviousMonth = useCallback(() => {
35+
setCurrentCalendarMonth(sub(currentCalendarMonth, { months: 1 }));
36+
}, [currentCalendarMonth]);
37+
38+
const handleNextMonth = useCallback(() => {
39+
setCurrentCalendarMonth(add(currentCalendarMonth, { months: 1 }));
40+
}, [currentCalendarMonth]);
41+
42+
return (
43+
<View>
44+
<BasicCalendar
45+
calendarActiveDateRanges={calendarActiveDateRanges}
46+
calendarMonthId={toDateId(currentCalendarMonth)}
47+
getCalendarWeekDayFormat={format("E")}
48+
calendarFirstDayOfWeek="sunday"
49+
onCalendarDayPress={handleDayPress}
50+
onNextMonthPress={handleNextMonth}
51+
onPreviousMonthPress={handlePreviousMonth}
52+
/>
53+
</View>
54+
);
55+
}

0 commit comments

Comments
 (0)