* feat: #4452 improve calendar design * fix: format issues --------- Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Box, Container, Flex, Popover, Text, useMantineTheme } from "@mantine/core";
|
import { Box, Container, Flex, Popover, Text, useMantineTheme } from "@mantine/core";
|
||||||
|
import { useElementSize } from "@mantine/hooks";
|
||||||
|
|
||||||
import { useRequiredBoard } from "@homarr/boards/context";
|
import { useRequiredBoard } from "@homarr/boards/context";
|
||||||
import type { CalendarEvent } from "@homarr/integrations/types";
|
import type { CalendarEvent } from "@homarr/integrations/types";
|
||||||
@@ -17,6 +18,7 @@ interface CalendarDayProps {
|
|||||||
export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: CalendarDayProps) => {
|
export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: CalendarDayProps) => {
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
const { primaryColor } = useMantineTheme();
|
const { primaryColor } = useMantineTheme();
|
||||||
|
const { ref, height } = useElementSize();
|
||||||
const board = useRequiredBoard();
|
const board = useRequiredBoard();
|
||||||
const mantineTheme = useMantineTheme();
|
const mantineTheme = useMantineTheme();
|
||||||
const actualItemRadius = mantineTheme.radius[board.itemRadius];
|
const actualItemRadius = mantineTheme.radius[board.itemRadius];
|
||||||
@@ -25,6 +27,8 @@ export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: C
|
|||||||
const shouldScaleDown = minAxisSize < 350;
|
const shouldScaleDown = minAxisSize < 350;
|
||||||
const isSmall = rootHeight < 256;
|
const isSmall = rootHeight < 256;
|
||||||
|
|
||||||
|
const isTooSmallForIndicators = height < 30;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
position="bottom"
|
position="bottom"
|
||||||
@@ -47,6 +51,7 @@ export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: C
|
|||||||
pt={isSmall ? 0 : 10}
|
pt={isSmall ? 0 : 10}
|
||||||
pb={isSmall ? 0 : 10}
|
pb={isSmall ? 0 : 10}
|
||||||
m={0}
|
m={0}
|
||||||
|
ref={ref}
|
||||||
bd={`2px solid ${opened && !disabled ? primaryColor : "transparent"}`}
|
bd={`2px solid ${opened && !disabled ? primaryColor : "transparent"}`}
|
||||||
style={{
|
style={{
|
||||||
alignContent: "center",
|
alignContent: "center",
|
||||||
@@ -62,7 +67,7 @@ export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: C
|
|||||||
<Text ta={"center"} size={shouldScaleDown ? "xs" : "md"} lh={1}>
|
<Text ta={"center"} size={shouldScaleDown ? "xs" : "md"} lh={1}>
|
||||||
{date.getDate()}
|
{date.getDate()}
|
||||||
</Text>
|
</Text>
|
||||||
<NotificationIndicator events={events} isSmall={isSmall} />
|
{!isTooSmallForIndicators && <NotificationIndicator events={events} isSmall={isSmall} />}
|
||||||
</Container>
|
</Container>
|
||||||
</Popover.Target>
|
</Popover.Target>
|
||||||
{/* Popover has some offset on the left side, padding is removed because of scrollarea paddings */}
|
{/* Popover has some offset on the left side, padding is removed because of scrollarea paddings */}
|
||||||
@@ -82,9 +87,19 @@ const NotificationIndicator = ({ events, isSmall }: NotificationIndicatorProps)
|
|||||||
const notificationEvents = [...new Set(events.map((event) => event.indicatorColor))].filter(String);
|
const notificationEvents = [...new Set(events.map((event) => event.indicatorColor))].filter(String);
|
||||||
/* position bottom is lower when small to not be on top of number*/
|
/* position bottom is lower when small to not be on top of number*/
|
||||||
return (
|
return (
|
||||||
<Flex w="75%" pos={"absolute"} bottom={isSmall ? 4 : 10} left={"12.5%"} p={0} direction={"row"} justify={"center"}>
|
<Flex
|
||||||
|
w="75%"
|
||||||
|
align={"center"}
|
||||||
|
pos={"absolute"}
|
||||||
|
gap={3}
|
||||||
|
bottom={isSmall ? 4 : 10}
|
||||||
|
left={"12.5%"}
|
||||||
|
p={0}
|
||||||
|
direction={"row"}
|
||||||
|
justify={"center"}
|
||||||
|
>
|
||||||
{notificationEvents.map((notificationEvent) => {
|
{notificationEvents.map((notificationEvent) => {
|
||||||
return <Box key={notificationEvent} bg={notificationEvent} h={2} p={0} style={{ flex: 1, borderRadius: 5 }} />;
|
return <Box key={notificationEvent} bg={notificationEvent} h={4} w={4} p={0} style={{ borderRadius: 999 }} />;
|
||||||
})}
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -124,12 +124,17 @@ const CalendarBase = ({ isEditMode, events, month, setMonth, options }: Calendar
|
|||||||
},
|
},
|
||||||
monthCell: {
|
monthCell: {
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
|
position: "relative",
|
||||||
},
|
},
|
||||||
day: {
|
day: {
|
||||||
borderRadius: actualItemRadius,
|
borderRadius: actualItemRadius,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
position: "relative",
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
},
|
},
|
||||||
month: {
|
month: {
|
||||||
height: "100%",
|
height: "100%",
|
||||||
@@ -137,6 +142,9 @@ const CalendarBase = ({ isEditMode, events, month, setMonth, options }: Calendar
|
|||||||
weekday: {
|
weekday: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
},
|
},
|
||||||
|
weekdaysRow: {
|
||||||
|
height: 22,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
renderDay={(tileDate) => {
|
renderDay={(tileDate) => {
|
||||||
const eventsForDate = normalizedEvents
|
const eventsForDate = normalizedEvents
|
||||||
|
|||||||
Reference in New Issue
Block a user