Shared:Calendar:Add scroll to calendar.
This commit is contained in:
parent
1bfa73ac4b
commit
49b78e1e15
@ -2,11 +2,13 @@ import IconCalendar from "PUBLIC_DIR/images/calendar.info.panel.react.svg?url";
|
|||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {Calendar} from "@docspace/shared/components/calendar"
|
import { Calendar } from "@docspace/shared/components/calendar";
|
||||||
import { Portal } from "@docspace/shared/components/portal";
|
|
||||||
import { isMobile } from "@docspace/shared/utils";
|
import { isMobile } from "@docspace/shared/utils";
|
||||||
import { ReactSVG } from "react-svg";
|
import { ReactSVG } from "react-svg";
|
||||||
|
|
||||||
|
const heightCalendar = 376;
|
||||||
|
const heightCalendarMobile = 420;
|
||||||
|
|
||||||
const StyledCalendarComponent = styled.div`
|
const StyledCalendarComponent = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -17,8 +19,10 @@ const StyledCalendarComponent = styled.div`
|
|||||||
|
|
||||||
const StyledCalendar = styled(Calendar)`
|
const StyledCalendar = styled(Calendar)`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 134px;
|
top: 20px;
|
||||||
right: 16px;
|
right: -30px;
|
||||||
|
|
||||||
|
height: ${(props) => props.height + "px"};
|
||||||
|
|
||||||
${(props) =>
|
${(props) =>
|
||||||
props.isMobile &&
|
props.isMobile &&
|
||||||
@ -27,24 +31,42 @@ const StyledCalendar = styled(Calendar)`
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
top: auto;
|
top: auto;
|
||||||
right: auto;
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
height: ${heightCalendarMobile + "px"};
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const CalendarComponent = ({ roomCreationDate, setCalendarDay }) => {
|
const CalendarComponent = ({ roomCreationDate, setCalendarDay }) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [selectedDate, setSelectedDate] = useState(null);
|
const [selectedDate, setSelectedDate] = useState(null);
|
||||||
|
const [height, setHeight] = useState(heightCalendar);
|
||||||
|
|
||||||
const calendarRef = useRef();
|
const calendarRef = useRef();
|
||||||
const calendarButtonRef = useRef();
|
const calendarButtonRef = useRef();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.addEventListener("click", handleClick, { capture: true });
|
document.addEventListener("click", handleClick, { capture: true });
|
||||||
|
window.addEventListener("resize", onChangeHeight);
|
||||||
|
onChangeHeight();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("click", handleClick, { capture: true });
|
document.removeEventListener("click", handleClick, { capture: true });
|
||||||
|
window.removeEventListener("resize", onChangeHeight);
|
||||||
setCalendarDay(null);
|
setCalendarDay(null);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onChangeHeight = () => {
|
||||||
|
const hightTop = calendarButtonRef?.current?.getBoundingClientRect().top;
|
||||||
|
const hightIconCalendar = 20;
|
||||||
|
const hightWindow = document.documentElement.clientHeight;
|
||||||
|
const hightScroll = hightWindow - hightIconCalendar - hightTop;
|
||||||
|
|
||||||
|
if (hightScroll !== heightCalendar && hightScroll > heightCalendar) {
|
||||||
|
setHeight(heightCalendar);
|
||||||
|
} else setHeight(hightScroll);
|
||||||
|
};
|
||||||
|
|
||||||
const handleClick = (e) => {
|
const handleClick = (e) => {
|
||||||
!calendarButtonRef?.current?.contains(e.target) &&
|
!calendarButtonRef?.current?.contains(e.target) &&
|
||||||
!calendarRef?.current?.contains(e.target) &&
|
!calendarRef?.current?.contains(e.target) &&
|
||||||
@ -74,17 +96,15 @@ const CalendarComponent = ({ roomCreationDate, setCalendarDay }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<Portal
|
<StyledCalendar
|
||||||
element={
|
height={height}
|
||||||
<StyledCalendar
|
setSelectedDate={onDateSet}
|
||||||
setSelectedDate={onDateSet}
|
selectedDate={selectedDate}
|
||||||
selectedDate={selectedDate}
|
minDate={new Date(formattedRoomCreationDate)}
|
||||||
minDate={new Date(formattedRoomCreationDate)}
|
maxDate={new Date()}
|
||||||
maxDate={new Date()}
|
forwardedRef={calendarRef}
|
||||||
forwardedRef={calendarRef}
|
isMobile={isMobile()}
|
||||||
isMobile={isMobile()}
|
isScroll={!isMobile()}
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</StyledCalendarComponent>
|
</StyledCalendarComponent>
|
||||||
|
@ -78,6 +78,7 @@ ButtonsContainer.displayName = "ButtonsContainer";
|
|||||||
const CalendarContainer = styled.div<{
|
const CalendarContainer = styled.div<{
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
big?: boolean;
|
big?: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}>`
|
}>`
|
||||||
${(props) =>
|
${(props) =>
|
||||||
!props.isMobile &&
|
!props.isMobile &&
|
||||||
@ -109,19 +110,37 @@ const CalendarContainer = styled.div<{
|
|||||||
props.big ? "repeat(4, 1fr)" : "repeat(7, 1fr)"};
|
props.big ? "repeat(4, 1fr)" : "repeat(7, 1fr)"};
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: ${(props) => (props.big ? "14px 6px 6px 6px" : "0 6px")};
|
padding: ${(props) => (props.big ? "14px 6px 6px 6px" : "0 6px")};
|
||||||
|
${(props) =>
|
||||||
|
props.isScroll &&
|
||||||
|
css`
|
||||||
|
margin-bottom: 28px;
|
||||||
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
CalendarContainer.defaultProps = { theme: Base };
|
CalendarContainer.defaultProps = { theme: Base };
|
||||||
|
|
||||||
const Container = styled.div<{ isMobile?: boolean }>`
|
const Container = styled.div<{ isMobile?: boolean; isScroll?: boolean }>`
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: ${(props) => (props.isMobile ? "100%" : "362px")};
|
width: ${(props) => (props.isMobile ? "100%" : "362px")};
|
||||||
height: ${(props) => (props.isMobile ? "420px" : "376px")};
|
height: ${(props) => (props.isMobile ? "420px" : "376px")};
|
||||||
padding: ${(props) => (props.isMobile ? "16px" : "30px 28px 28px 28px")};
|
padding: ${(props) =>
|
||||||
|
props.isMobile
|
||||||
|
? "16px"
|
||||||
|
: props.isScroll
|
||||||
|
? "0px 0px 0px 28px"
|
||||||
|
: "30px 28px 28px 28px"};
|
||||||
box-shadow: ${(props) => props.theme.calendar.boxShadow};
|
box-shadow: ${(props) => props.theme.calendar.boxShadow};
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
z-index: 320;
|
z-index: 320;
|
||||||
background-color: ${(props) => props.theme.backgroundColor};
|
background-color: ${(props) => props.theme.backgroundColor};
|
||||||
|
|
||||||
|
${(props) =>
|
||||||
|
props.isScroll &&
|
||||||
|
css`
|
||||||
|
header {
|
||||||
|
padding: 30px 23px 0 12px !important;
|
||||||
|
}
|
||||||
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
Container.defaultProps = { theme: Base };
|
Container.defaultProps = { theme: Base };
|
||||||
@ -317,6 +336,7 @@ Weekday.defaultProps = { theme: Base };
|
|||||||
const StyledContainerTheme = styled(Container)<{
|
const StyledContainerTheme = styled(Container)<{
|
||||||
$currentColorScheme?: TColorScheme;
|
$currentColorScheme?: TColorScheme;
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}>`
|
}>`
|
||||||
${HeaderActionIcon} {
|
${HeaderActionIcon} {
|
||||||
border-color: ${(props) => props.$currentColorScheme?.main?.accent};
|
border-color: ${(props) => props.$currentColorScheme?.main?.accent};
|
||||||
|
@ -30,6 +30,7 @@ import { useTheme } from "styled-components";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import "moment/locale/ar-sa";
|
import "moment/locale/ar-sa";
|
||||||
|
|
||||||
|
import { Scrollbar } from "@docspace/shared/components/scrollbar";
|
||||||
import { Days, Months, Years } from "./sub-components";
|
import { Days, Months, Years } from "./sub-components";
|
||||||
|
|
||||||
import { getValidDates } from "./utils";
|
import { getValidDates } from "./utils";
|
||||||
@ -49,6 +50,7 @@ const Calendar = ({
|
|||||||
onChange,
|
onChange,
|
||||||
isMobile,
|
isMobile,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
|
isScroll = false,
|
||||||
}: CalendarProps) => {
|
}: CalendarProps) => {
|
||||||
moment.locale(locale);
|
moment.locale(locale);
|
||||||
|
|
||||||
@ -105,6 +107,49 @@ const Calendar = ({
|
|||||||
setObservedDate(date);
|
setObservedDate(date);
|
||||||
}, [initialDate, maxDate, minDate]);
|
}, [initialDate, maxDate, minDate]);
|
||||||
|
|
||||||
|
const CalendarBodyNode =
|
||||||
|
selectedScene === 0 ? (
|
||||||
|
<Days
|
||||||
|
observedDate={observedDate}
|
||||||
|
setObservedDate={setObservedDate}
|
||||||
|
setSelectedScene={setSelectedScene}
|
||||||
|
selectedDate={selectedDate}
|
||||||
|
handleDateChange={handleDateChange}
|
||||||
|
minDate={resultMinDate}
|
||||||
|
maxDate={resultMaxDate}
|
||||||
|
isMobile={isMobile || false}
|
||||||
|
isScroll={isScroll}
|
||||||
|
/>
|
||||||
|
) : selectedScene === 1 ? (
|
||||||
|
<Months
|
||||||
|
observedDate={observedDate}
|
||||||
|
setObservedDate={setObservedDate}
|
||||||
|
setSelectedScene={setSelectedScene}
|
||||||
|
selectedDate={selectedDate}
|
||||||
|
minDate={resultMinDate}
|
||||||
|
maxDate={resultMaxDate}
|
||||||
|
isMobile={isMobile || false}
|
||||||
|
isScroll={isScroll}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Years
|
||||||
|
observedDate={observedDate}
|
||||||
|
setObservedDate={setObservedDate}
|
||||||
|
setSelectedScene={setSelectedScene}
|
||||||
|
selectedDate={selectedDate}
|
||||||
|
minDate={resultMinDate}
|
||||||
|
maxDate={resultMaxDate}
|
||||||
|
isMobile={isMobile || false}
|
||||||
|
isScroll={isScroll}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const CalendarNode = isScroll ? (
|
||||||
|
<Scrollbar>{CalendarBodyNode}</Scrollbar>
|
||||||
|
) : (
|
||||||
|
CalendarBodyNode
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainerTheme
|
<StyledContainerTheme
|
||||||
id={id}
|
id={id}
|
||||||
@ -114,39 +159,9 @@ const Calendar = ({
|
|||||||
ref={forwardedRef}
|
ref={forwardedRef}
|
||||||
$currentColorScheme={theme?.currentColorScheme}
|
$currentColorScheme={theme?.currentColorScheme}
|
||||||
data-testid="calendar"
|
data-testid="calendar"
|
||||||
|
isScroll={isScroll}
|
||||||
>
|
>
|
||||||
{selectedScene === 0 ? (
|
{CalendarNode}
|
||||||
<Days
|
|
||||||
observedDate={observedDate}
|
|
||||||
setObservedDate={setObservedDate}
|
|
||||||
setSelectedScene={setSelectedScene}
|
|
||||||
selectedDate={selectedDate}
|
|
||||||
handleDateChange={handleDateChange}
|
|
||||||
minDate={resultMinDate}
|
|
||||||
maxDate={resultMaxDate}
|
|
||||||
isMobile={isMobile || false}
|
|
||||||
/>
|
|
||||||
) : selectedScene === 1 ? (
|
|
||||||
<Months
|
|
||||||
observedDate={observedDate}
|
|
||||||
setObservedDate={setObservedDate}
|
|
||||||
setSelectedScene={setSelectedScene}
|
|
||||||
selectedDate={selectedDate}
|
|
||||||
minDate={resultMinDate}
|
|
||||||
maxDate={resultMaxDate}
|
|
||||||
isMobile={isMobile || false}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Years
|
|
||||||
observedDate={observedDate}
|
|
||||||
setObservedDate={setObservedDate}
|
|
||||||
setSelectedScene={setSelectedScene}
|
|
||||||
selectedDate={selectedDate}
|
|
||||||
minDate={resultMinDate}
|
|
||||||
maxDate={resultMaxDate}
|
|
||||||
isMobile={isMobile || false}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</StyledContainerTheme>
|
</StyledContainerTheme>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -49,6 +49,7 @@ export interface CalendarProps {
|
|||||||
initialDate?: moment.Moment | Date;
|
initialDate?: moment.Moment | Date;
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
forwardedRef?: React.RefObject<HTMLDivElement>;
|
forwardedRef?: React.RefObject<HTMLDivElement>;
|
||||||
|
isScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DaysProps {
|
export interface DaysProps {
|
||||||
@ -60,6 +61,7 @@ export interface DaysProps {
|
|||||||
minDate: moment.Moment;
|
minDate: moment.Moment;
|
||||||
maxDate: moment.Moment;
|
maxDate: moment.Moment;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DaysHeaderProps {
|
export interface DaysHeaderProps {
|
||||||
@ -78,6 +80,7 @@ export interface DaysBodyProps {
|
|||||||
minDate: moment.Moment;
|
minDate: moment.Moment;
|
||||||
maxDate: moment.Moment;
|
maxDate: moment.Moment;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HeaderButtonsProps {
|
export interface HeaderButtonsProps {
|
||||||
@ -96,6 +99,7 @@ export interface MonthsProps {
|
|||||||
minDate: moment.Moment;
|
minDate: moment.Moment;
|
||||||
maxDate: moment.Moment;
|
maxDate: moment.Moment;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MonthsBodyProps {
|
export interface MonthsBodyProps {
|
||||||
@ -106,6 +110,7 @@ export interface MonthsBodyProps {
|
|||||||
minDate: moment.Moment;
|
minDate: moment.Moment;
|
||||||
maxDate: moment.Moment;
|
maxDate: moment.Moment;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MonthsHeaderProps {
|
export interface MonthsHeaderProps {
|
||||||
@ -125,6 +130,7 @@ export interface YearsProps {
|
|||||||
minDate: moment.Moment;
|
minDate: moment.Moment;
|
||||||
maxDate: moment.Moment;
|
maxDate: moment.Moment;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
isScroll?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface YearsHeaderProps {
|
export interface YearsHeaderProps {
|
||||||
|
@ -38,6 +38,7 @@ export const Days = ({
|
|||||||
minDate,
|
minDate,
|
||||||
maxDate,
|
maxDate,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
isScroll,
|
||||||
}: DaysProps) => {
|
}: DaysProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -56,6 +57,7 @@ export const Days = ({
|
|||||||
minDate={minDate}
|
minDate={minDate}
|
||||||
maxDate={maxDate}
|
maxDate={maxDate}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
|
isScroll={isScroll}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -37,6 +37,7 @@ export const DaysBody = ({
|
|||||||
minDate,
|
minDate,
|
||||||
maxDate,
|
maxDate,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
isScroll,
|
||||||
}: DaysBodyProps) => {
|
}: DaysBodyProps) => {
|
||||||
const daysElements = getDayElements(
|
const daysElements = getDayElements(
|
||||||
observedDate,
|
observedDate,
|
||||||
@ -49,7 +50,7 @@ export const DaysBody = ({
|
|||||||
const weekdayElements = getWeekdayElements(isMobile);
|
const weekdayElements = getWeekdayElements(isMobile);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CalendarContainer isMobile={isMobile}>
|
<CalendarContainer isMobile={isMobile} isScroll={isScroll}>
|
||||||
{weekdayElements} {daysElements}
|
{weekdayElements} {daysElements}
|
||||||
</CalendarContainer>
|
</CalendarContainer>
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,7 @@ export const Months = ({
|
|||||||
minDate,
|
minDate,
|
||||||
maxDate,
|
maxDate,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
isScroll,
|
||||||
}: MonthsProps) => {
|
}: MonthsProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -57,6 +58,7 @@ export const Months = ({
|
|||||||
minDate={minDate}
|
minDate={minDate}
|
||||||
maxDate={maxDate}
|
maxDate={maxDate}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
|
isScroll={isScroll}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -37,6 +37,7 @@ export const MonthsBody = ({
|
|||||||
minDate,
|
minDate,
|
||||||
maxDate,
|
maxDate,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
isScroll,
|
||||||
}: MonthsBodyProps) => {
|
}: MonthsBodyProps) => {
|
||||||
const months = getCalendarMonths(observedDate);
|
const months = getCalendarMonths(observedDate);
|
||||||
const monthsElements = getMonthElements(
|
const monthsElements = getMonthElements(
|
||||||
@ -50,7 +51,7 @@ export const MonthsBody = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CalendarContainer big isMobile={isMobile}>
|
<CalendarContainer big isMobile={isMobile} isScroll={isScroll}>
|
||||||
{monthsElements}
|
{monthsElements}
|
||||||
</CalendarContainer>
|
</CalendarContainer>
|
||||||
);
|
);
|
||||||
|
@ -37,6 +37,7 @@ export const Years = ({
|
|||||||
minDate,
|
minDate,
|
||||||
maxDate,
|
maxDate,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
isScroll,
|
||||||
}: YearsProps) => {
|
}: YearsProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -55,6 +56,7 @@ export const Years = ({
|
|||||||
minDate={minDate}
|
minDate={minDate}
|
||||||
maxDate={maxDate}
|
maxDate={maxDate}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
|
isScroll={isScroll}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,7 @@ export const YearsBody = ({
|
|||||||
minDate,
|
minDate,
|
||||||
maxDate,
|
maxDate,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
isScroll,
|
||||||
}: YearsProps) => {
|
}: YearsProps) => {
|
||||||
const years = getCalendarYears(observedDate);
|
const years = getCalendarYears(observedDate);
|
||||||
const yearElements = getYearElements(
|
const yearElements = getYearElements(
|
||||||
@ -51,7 +52,7 @@ export const YearsBody = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CalendarContainer big isMobile={isMobile}>
|
<CalendarContainer big isMobile={isMobile} isScroll={isScroll}>
|
||||||
{yearElements}
|
{yearElements}
|
||||||
</CalendarContainer>
|
</CalendarContainer>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user