Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3 calendar #629

Merged
merged 7 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/calendar/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useState } from "react";
import styled, { css } from "styled-components";
import { V2_Color } from "../v2_color";
import { InternalCalendar } from "../shared/internal-calendar";
import { Border, Colour, Radius } from "../theme";
import { CalendarProps } from "./types";

export const Calendar = ({
Expand Down Expand Up @@ -58,8 +58,8 @@ const Wrapper = styled.div<StyleProps>`
${(props) => {
if (props.$hasBorder) {
return css`
border: 1px solid ${V2_Color.Neutral[5](props)};
border-radius: 12px;
border: ${Border["width-010"]} ${Border.solid} ${Colour.border};
border-radius: ${Radius.lg};
overflow: hidden;
`;
}
Expand Down
4 changes: 2 additions & 2 deletions src/shared/internal-calendar/calendar-dropdown.style.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from "styled-components";
import { V2_MediaQuery } from "../../v2_media";
import { MediaQuery } from "../../theme";

// =============================================================================
// STYLE INTERFACE
Expand All @@ -16,7 +16,7 @@ export const CalendarWrapper = styled.div<StyleProps>`
max-width: 41rem;
min-width: 21rem;

${V2_MediaQuery.MaxWidth.mobileL} {
${MediaQuery.MaxWidth.sm} {
min-width: 17.5rem;
}
`;
14 changes: 7 additions & 7 deletions src/shared/internal-calendar/calendar-manager.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { ChevronLeftIcon } from "@lifesg/react-icons/chevron-left";
import { ChevronRightIcon } from "@lifesg/react-icons/chevron-right";
import styled, { css } from "styled-components";
import { Button } from "../../button";
import { V2_Color } from "../../v2_color";
import { V2_TextStyleHelper } from "../../v2_text";
import { Colour, Font } from "../../theme";
import { ClickableIcon } from "../clickable-icon";

// =============================================================================
Expand All @@ -26,7 +25,7 @@ interface OverlayStyleProps {
// ICONS
// -----------------------------------------------------------------------------
const iconStyle = css`
color: ${V2_Color.Neutral[3]};
color: ${Colour.icon};
height: 1rem;
width: 1rem;
`;
Expand Down Expand Up @@ -72,7 +71,7 @@ export const OptionsOverlay = styled.div<OverlayStyleProps>`
left: 0;
height: 100%;
width: 100%;
background: ${V2_Color.Neutral[8]};
background: ${Colour.bg};

${(props) => {
if (!props.$visible) {
Expand Down Expand Up @@ -118,11 +117,12 @@ export const DropdownButton = styled.button<DropdownButtonStyleProps>`
}
`;
}
}}
}};
`;

export const DropdownText = styled.p`
${V2_TextStyleHelper.getTextStyle("H5", "regular")}
export const DropdownText = styled.span`
${Font["body-md-regular"]}
color: ${Colour["text"]};
`;

export const HeaderArrows = styled.div`
Expand Down
159 changes: 72 additions & 87 deletions src/shared/internal-calendar/day-cell/day-cell.style.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import styled, { css } from "styled-components";
import { V2_Color } from "../../../v2_color";
import { V2_Text, V2_TextStyleHelper } from "../../../v2_text";
import { Border, Colour, Font, FontSpec, Motion, Radius } from "../../../theme";
import { CellType, LabelType } from "./types";

// =============================================================================
// STYLE INTERFACES
// =============================================================================
interface StyleProps {
$type?: CellType;
$shadow?: boolean;
}

interface LabelStyleProps {
Expand All @@ -17,50 +15,55 @@ interface LabelStyleProps {
$interactive: boolean | null;
}

interface IndicatorStyleProps {
$disabled: boolean;
}

// =============================================================================
// HELPERS
// =============================================================================
const getCellStyle = (props: StyleProps) => {
let color = V2_Color.Neutral[8];
let border = "1px solid transparent";
let color = Colour.bg;
let borderColor: typeof color | string = "transparent";

switch (props.$type) {
case "current":
color = V2_Color.Accent.Light[5];
break;
case "hover-dash":
color = V2_Color.Accent.Light[6];
border = `1px dashed ${V2_Color.Accent.Light[4](props)}`;
case "hover-subtle":
color = Colour["bg-hover"];
borderColor = Colour["bg-hover"];
break;
case "hover-current":
color = V2_Color.Neutral[8];
border = `1px solid ${V2_Color.Primary(props)}`;
case "hover":
color = Colour["bg-hover-strong"];
borderColor = Colour["bg-hover-strong"];
break;
case "selected":
color = V2_Color.Accent.Light[5];
border = `1px solid ${V2_Color.Accent.Light[4](props)}`;
case "hover-outline":
color = Colour["bg-hover-subtle"];
borderColor = Colour["border-hover"];
break;
case "selected-outline":
color = V2_Color.Accent.Light[5];
border = `1px solid ${V2_Color.Primary(props)}`;
color = Colour["bg-selected"];
borderColor = Colour["border-selected"];
break;
case "overlap":
color = V2_Color.Accent.Light[4];
border = `1px solid ${V2_Color.Accent.Light[4](props)}`;
case "selected-outline-subtle":
color = Colour["bg-selected"];
borderColor = Colour["border-selected-subtle"];
break;
case "overlap-outline":
color = V2_Color.Accent.Light[4];
border = `1px solid ${V2_Color.Primary(props)}`;
case "selected-hover":
color = Colour["bg-selected-hover"];
// no border to give it an overlay effect
break;
case "selected-hover-outline":
color = Colour["bg-selected-hover"];
borderColor = Colour["border-selected-hover"];
break;
Comment on lines +30 to 57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondering if it is possible to align with UX on the naming of various states?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

due to the different possible combinations of elements across components, and the modular implementation of the day cell, the naming of CellType can't be 1:1 with the elements. but UX has suggested to include a mapping in Figma to bridge this difference

}

return { color, border };
return { color, borderColor };
};

// =============================================================================
// COMPONENTS
// =============================================================================
export const Cell = styled.div`
export const Cell = styled.div<StyleProps>`
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -73,17 +76,21 @@ const Half = styled.div<StyleProps>`
position: absolute;
height: 2.5rem;
width: 50%;
transition: ${Motion["duration-150"]} ${Motion["ease-default"]};
border: ${Border["width-010"]} ${Border["solid"]} transparent;
border-left: none;
border-right: none;

${(props) => {
if (!props.$type) {
return;
}
const { color, border } = getCellStyle(props);
const { color, borderColor } = getCellStyle(props);
return css`
background-color: ${color};
background-clip: content-box;
border-top: ${border};
border-bottom: ${border};
background-clip: border-box;
border-top-color: ${borderColor};
border-bottom-color: ${borderColor};
`;
}}
`;
Expand All @@ -96,25 +103,6 @@ export const RightHalf = styled(Half)`
right: 0;
`;

const HalfShadow = styled.div<StyleProps>`
z-index: -1;
box-shadow: 0 0 4px 1px ${V2_Color.Shadow.Accent};
position: absolute;
height: 100%;
width: 50%;
display: none;

${(props) => props.$shadow && "display: block;"}
`;

export const LeftHalfShadow = styled(HalfShadow)`
left: 0;
`;

export const RightHalfShadow = styled(HalfShadow)`
right: 0;
`;

export const Circle = styled.div<StyleProps>`
position: absolute;
z-index: 1;
Expand All @@ -124,51 +112,34 @@ export const Circle = styled.div<StyleProps>`
justify-content: center;
height: 2.5rem;
width: 2.5rem;
transition: ${Motion["duration-150"]} ${Motion["ease-default"]};

border: 1px solid transparent;
border-radius: 50%;
border: ${Border["width-010"]} ${Border["solid"]} transparent;
border-radius: ${Radius.md};

${(props) => {
if (props.$type) {
const { color, border } = getCellStyle(props);
const { color, borderColor } = getCellStyle(props);
return css`
background-color: ${color};
background-clip: content-box;
border: ${border};
border-color: ${borderColor};
`;
}
}}

${(props) =>
props.$shadow &&
css`
&:before {
content: "";
border-radius: 50%;
position: absolute;
height: 100%;
width: 100%;
}
`}
`;

export const LeftCircle = styled(Circle)`
right: calc(50% - 1.25rem);
clip-path: inset(-3px 1.25rem -3px -3px);
&:before {
box-shadow: -1px 0 4px 1px ${V2_Color.Shadow.Accent};
}
`;

export const RightCircle = styled(Circle)`
left: calc(50% - 1.25rem);
clip-path: inset(-3px -3px -3px 1.25rem);
&:before {
box-shadow: 1px 0 4px 1px ${V2_Color.Shadow.Accent};
}
`;

export const Label = styled(V2_Text.H5)<LabelStyleProps>`
export const Label = styled.div<LabelStyleProps>`
position: absolute;
top: 0;
bottom: 0;
Expand All @@ -179,7 +150,8 @@ export const Label = styled(V2_Text.H5)<LabelStyleProps>`
justify-content: center;
height: 2.5rem;
width: 2.5rem;
border-radius: 50%;
${Font["body-md-regular"]}
transition: ${Motion["duration-150"]} ${Motion["ease-default"]};

cursor: ${(props) => {
if (props.$interactive) {
Expand All @@ -195,31 +167,35 @@ export const Label = styled(V2_Text.H5)<LabelStyleProps>`
const { $disabled, $type } = props;

if ($disabled) {
if ($type === "selected") {
return css`
${V2_TextStyleHelper.getTextStyle("H5", "semibold")};
color: ${V2_Color.Accent.Light[2]};
`;
}

return css`
color: ${V2_Color.Neutral[4]};
color: ${Colour["text-disabled-subtlest"]};
`;
}

switch ($type) {
case "selected":
return css`
${V2_TextStyleHelper.getTextStyle("H5", "semibold")};
color: ${V2_Color.Primary};
font-weight: ${FontSpec["weight-semibold"]};
color: ${Colour["text-selected"]};
`;
case "selected-hover":
return css`
font-weight: ${FontSpec["weight-semibold"]};
color: ${Colour["text-selected-hover"]};
`;
case "current":
return css`
color: ${V2_Color.Neutral[3]};
font-weight: ${FontSpec["weight-semibold"]};
color: ${Colour["text-primary"]};
`;
case "hover":
return css`
font-weight: ${FontSpec["weight-semibold"]};
color: ${Colour["text-hover"]};
`;
case "unavailable":
return css`
color: ${V2_Color.Neutral[4]};
color: ${Colour["text-disabled-subtlest"]};
`;
case "hidden":
return css`
Expand All @@ -228,8 +204,17 @@ export const Label = styled(V2_Text.H5)<LabelStyleProps>`
case "available":
default:
return css`
color: ${V2_Color.Neutral[1]};
color: ${Colour.text};
`;
}
}}
`;

export const Indicator = styled.div<IndicatorStyleProps>`
position: absolute;
width: 4px;
height: 4px;
background-color: currentColor;
border-radius: 50%;
bottom: 4px;
`;
Loading
Loading