diff --git a/front/src/components/form/DatePicker.tsx b/front/src/components/form/DatePicker.tsx index f4f1d9a59..f58f1d648 100644 --- a/front/src/components/form/DatePicker.tsx +++ b/front/src/components/form/DatePicker.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; import React, { ReactElement, forwardRef, useState } from 'react'; -import ReactDatePicker from 'react-datepicker'; +import ReactDatePicker, { CalendarContainerProps } from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; @@ -9,12 +9,17 @@ export type DatePickerProps = { date: Date; onChangeHandler: (date: Date) => void; customInput?: ReactElement; + customContainer?(props: CalendarContainerProps): React.ReactNode; }; const StyledContainer = styled.div` & .react-datepicker { border-color: ${(props) => props.theme.primaryBorder}; + background: transparent; font-family: 'Inter'; + font-size: ${(props) => props.theme.fontSizeMedium}; + border: none; + display: block; } & .react-datepicker__triangle::after { @@ -25,17 +30,150 @@ const StyledContainer = styled.div` display: none; } + // Header + & .react-datepicker__header { - background-color: ${(props) => props.theme.primaryBackground}; - border-bottom-color: ${(props) => props.theme.primaryBorder}; + background: transparent; + border: none; + } + + & .react-datepicker__header__dropdown { + display: flex; + margin-left: ${(props) => props.theme.spacing(1)}; + margin-bottom: ${(props) => props.theme.spacing(1)}; + } + + & .react-datepicker__month-dropdown-container, + & .react-datepicker__year-dropdown-container { + text-align: left; + border-radius: 4px; + margin-left: ${(props) => props.theme.spacing(1)}; + margin-right: 0; + padding: ${(props) => props.theme.spacing(2)}; + padding-right: ${(props) => props.theme.spacing(4)}; + background-color: ${(props) => props.theme.tertiaryBackground}; + } + + & .react-datepicker__month-read-view--down-arrow, + & .react-datepicker__year-read-view--down-arrow { + height: 5px; + width: 5px; + border-width: 1px 1px 0 0; + border-color: ${(props) => props.theme.text40}; + top: 3px; + right: -6px; + } + + & .react-datepicker__year-read-view, + & .react-datepicker__month-read-view { + padding-right: ${(props) => props.theme.spacing(2)}; + } + + & .react-datepicker__month-dropdown-container { + width: 80px; + } + + & .react-datepicker__year-dropdown-container { + width: 50px; + } + + & .react-datepicker__month-dropdown { + left: ${(props) => props.theme.spacing(2)}; + top: ${(props) => props.theme.spacing(2)}; + width: calc(80px + ${(props) => props.theme.spacing(6)}); + border: ${(props) => props.theme.primaryBorder}; + } + + & .react-datepicker__year-dropdown { + left: calc(${(props) => props.theme.spacing(9)} + 80px); + top: ${(props) => props.theme.spacing(2)}; + width: calc(50px + ${(props) => props.theme.spacing(6)}); + border: ${(props) => props.theme.primaryBorder}; + } + + & .react-datepicker__navigation--years { + display: none; + } + + & .react-datepicker__month-option--selected, + & .react-datepicker__year-option--selected { + display: none; + } + + & .react-datepicker__year-option, + & .react-datepicker__month-option { + line-height: 32px; + text-align: left; + padding-left: ${(props) => props.theme.spacing(2)}; + width: calc(100% - ${(props) => props.theme.spacing(2)}); + background-color: ${(props) => props.theme.tertiaryBackground}; + + &:hover { + color: ${(props) => props.theme.text100}; + font-weight: bold; + } + } + + & .react-datepicker__current-month { + display: none; + } + + & .react-datepicker__day-name { + color: ${(props) => props.theme.text60}; + width: 34px; + height: 40px; + line-height: 40px; + } + + // Days + + & .react-datepicker__month { + margin-top: 0; + } + + & .react-datepicker__day { + width: 34px; + height: 34px; + line-height: 34px; } & .react-datepicker__day--selected { background-color: ${(props) => props.theme.blue}; } + + & .react-datepicker__navigation--previous { + right: 44px; + top: 12px; + left: auto; + } + + & .react-datepicker__navigation--next { + right: 6px; + top: 12px; + } + + & .react-datepicker__navigation-icon::before { + height: 7px; + width: 7px; + border-width: 1px 1px 0 0; + border-color: ${(props) => props.theme.text40}; + } + + & .react-datepicker__day--outside-month { + color: ${(props) => props.theme.text40}; + } + + & .react-datepicker__day--keyboard-selected { + background-color: inherit; + } `; -function DatePicker({ date, onChangeHandler, customInput }: DatePickerProps) { +function DatePicker({ + date, + onChangeHandler, + customInput, + customContainer, +}: DatePickerProps) { const [startDate, setStartDate] = useState(date); type DivProps = React.HTMLProps; @@ -58,11 +196,14 @@ function DatePicker({ date, onChangeHandler, customInput }: DatePickerProps) { { setStartDate(date); onChangeHandler(date); }} customInput={customInput ? customInput : } + calendarContainer={customContainer ? customContainer : undefined} /> ); diff --git a/front/src/components/table/editable-cell/EditableDate.tsx b/front/src/components/table/editable-cell/EditableDate.tsx index 89a8b79dd..637979707 100644 --- a/front/src/components/table/editable-cell/EditableDate.tsx +++ b/front/src/components/table/editable-cell/EditableDate.tsx @@ -2,6 +2,8 @@ import styled from '@emotion/styled'; import { forwardRef, useState } from 'react'; import EditableCellWrapper from './EditableCellWrapper'; import DatePicker from '../../form/DatePicker'; +import { CalendarContainer } from 'react-datepicker'; +import { modalBackground } from '../../../layout/styles/themes'; export type EditableDateProps = { value: Date; @@ -13,6 +15,21 @@ const StyledContainer = styled.div` display: flex; align-items: center; `; + +export type StyledCalendarContainerProps = { + editModeHorizontalAlign?: 'left' | 'right'; +}; + +const StyledCalendarContainer = styled.div` + position: absolute; + border: 1px solid ${(props) => props.theme.primaryBorder}; + border-radius: 8px; + width: 280px; + box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.09); + z-index: 1; + left: -10px; + ${modalBackground}; +`; function EditableDate({ value, changeHandler, @@ -36,6 +53,24 @@ function EditableDate({ ), ); + interface DatePickerContainerProps { + className?: string; + children: React.ReactNode; + } + + const DatePickerContainer = ({ + className, + children, + }: DatePickerContainerProps) => { + return ( + + +
{children}
+
+
+ ); + }; + return ( } + customContainer={DatePickerContainer} /> } diff --git a/front/src/layout/styles/themes.ts b/front/src/layout/styles/themes.ts index c87ce2661..1c304d3b1 100644 --- a/front/src/layout/styles/themes.ts +++ b/front/src/layout/styles/themes.ts @@ -27,7 +27,7 @@ const lightThemeSpecific = { purpleBackground: '#e0e0ff', yellowBackground: '#fff2e7', - secondaryBackgroundSmallTransparency: 'rgba(252, 252, 252, 0.8)', + secondaryBackgroundSmallTransparency: 'rgba(252, 252, 252, 0.97)', primaryBorder: 'rgba(0, 0, 0, 0.08)', @@ -59,7 +59,7 @@ const darkThemeSpecific: typeof lightThemeSpecific = { purpleBackground: '#1111b7', yellowBackground: '#cc660a', - secondaryBackgroundSmallTransparency: 'rgba(23, 23, 23, 0.8)', + secondaryBackgroundSmallTransparency: 'rgba(23, 23, 23, 0.97)', primaryBorder: 'rgba(255, 255, 255, 0.08)', @@ -83,7 +83,6 @@ const darkThemeSpecific: typeof lightThemeSpecific = { export const modalBackground = (props: any) => css` - backdrop-filter: blur(20px); background: ${props.theme.secondaryBackgroundSmallTransparency}; `;