) => {
+ if (onClick) onClick(event, data);
+ },
+ [onClick, data],
+ );
- return (
-
-
-
- );
-};
+ return (
+
+
+
+ );
+ },
+);
export default BodyCell;
diff --git a/src/components/BodyCellContent.tsx b/src/components/BodyCellContent.tsx
index 2e8c574..239da4a 100644
--- a/src/components/BodyCellContent.tsx
+++ b/src/components/BodyCellContent.tsx
@@ -1,9 +1,9 @@
-import React from 'react';
+import React, { memo } from 'react';
import { BodyCellData, SlotComponentProps } from '../types';
import { getBodyCellContent } from '../helpers';
export type BodyCellContentProps = SlotComponentProps<'div', { data: BodyCellData; locale?: string }>;
-const BodyCellContent = ({ data, locale, ...rest }: BodyCellContentProps): JSX.Element => {getBodyCellContent(data, locale)}
;
+const BodyCellContent = memo(({ data, locale, ...rest }: BodyCellContentProps): JSX.Element => {getBodyCellContent(data, locale)}
);
export default BodyCellContent;
diff --git a/src/components/BodyRow.tsx b/src/components/BodyRow.tsx
index 2dfbbf2..4246a62 100644
--- a/src/components/BodyRow.tsx
+++ b/src/components/BodyRow.tsx
@@ -1,4 +1,4 @@
-import React, { useMemo, useRef, useEffect } from 'react';
+import React, { useMemo, useRef, useEffect, memo } from 'react';
import useOnScreen from '../hooks/useOnScreen';
import { getCellAttributes } from '../helpers';
import { VisibilityMatrix, SlotRefComponentProps } from '../types';
@@ -30,58 +30,60 @@ export type BodyRowPrivateProps = {
};
};
-const BodyRow = ({
- numberOfWeek,
- numberOfTodayWeek,
- startRenderOnCurrentWeek,
- startDate,
- locale,
- visibilityMatrix,
- updateVisibilityMatrix,
- numberOfRowsPreRender,
- slots,
- slotProps,
-}: BodyRowPrivateProps): JSX.Element => {
- const ref = useRef(null);
- const shouldScroll = useRef(startRenderOnCurrentWeek && numberOfWeek === numberOfTodayWeek);
- const isVisible = useOnScreen(ref);
- const shouldRender = useMemo(
- () =>
- visibilityMatrix[numberOfWeek] ||
- Array(numberOfRowsPreRender)
- .fill(null)
- .some((_, idx) => visibilityMatrix[numberOfWeek - idx]),
- [visibilityMatrix, numberOfWeek, numberOfRowsPreRender],
- );
- const data = useMemo(() => {
- if (!startDate || !shouldRender) return [];
- const dates = Array.from(Array(7).keys()).map(day => getCellAttributes(startDate, numberOfWeek, day, locale));
- return dates;
- }, [startDate, numberOfWeek, locale, shouldRender]);
- const RootSlot = useMemo(() => slots?.root || 'ul', [slots]);
- const rootProps = useMemo(() => ({ ...(slotProps?.root || {}), className: classnames(styles.body__row, slotProps?.root?.className) }), [slotProps]);
+const BodyRow = memo(
+ ({
+ numberOfWeek,
+ numberOfTodayWeek,
+ startRenderOnCurrentWeek,
+ startDate,
+ locale,
+ visibilityMatrix,
+ updateVisibilityMatrix,
+ numberOfRowsPreRender,
+ slots,
+ slotProps,
+ }: BodyRowPrivateProps): JSX.Element => {
+ const ref = useRef(null);
+ const shouldScroll = useRef(startRenderOnCurrentWeek && numberOfWeek === numberOfTodayWeek);
+ const isVisible = useOnScreen(ref);
+ const shouldRender = useMemo(
+ () =>
+ visibilityMatrix[numberOfWeek] ||
+ Array(numberOfRowsPreRender)
+ .fill(null)
+ .some((_, idx) => visibilityMatrix[numberOfWeek - idx]),
+ [visibilityMatrix, numberOfWeek, numberOfRowsPreRender],
+ );
+ const data = useMemo(() => {
+ if (!startDate || !shouldRender) return [];
+ const dates = Array.from(Array(7).keys()).map(day => getCellAttributes(startDate, numberOfWeek, day, locale));
+ return dates;
+ }, [startDate, numberOfWeek, locale, shouldRender]);
+ const RootSlot = useMemo(() => slots?.root || 'ul', [slots]);
+ const rootProps = useMemo(() => ({ ...(slotProps?.root || {}), className: classnames(styles.body__row, slotProps?.root?.className) }), [slotProps]);
- useEffect(() => {
- if (isVisible && !shouldRender && updateVisibilityMatrix) updateVisibilityMatrix(numberOfWeek);
- }, [isVisible, shouldRender, updateVisibilityMatrix, numberOfWeek]);
+ useEffect(() => {
+ if (isVisible && !shouldRender && updateVisibilityMatrix) updateVisibilityMatrix(numberOfWeek);
+ }, [isVisible, shouldRender, updateVisibilityMatrix, numberOfWeek]);
- useEffect(() => {
- if (ref.current && shouldScroll.current) ref.current.scrollIntoView();
- }, []);
+ useEffect(() => {
+ if (ref.current && shouldScroll.current) ref.current.scrollIntoView();
+ }, []);
- return (
-
- {data.map(cell => (
-
- ))}
-
- );
-};
+ return (
+
+ {data.map(cell => (
+
+ ))}
+
+ );
+ },
+);
export default BodyRow;
diff --git a/src/components/Container.tsx b/src/components/Container.tsx
index a458a3b..5307e29 100644
--- a/src/components/Container.tsx
+++ b/src/components/Container.tsx
@@ -17,8 +17,7 @@ export type ContainerPrivateProps = {
const Container = memo(
({ children, slots, slotProps }: ContainerPrivateProps): JSX.Element => {
- const containerClassName = classnames(styles.calendar, slotProps?.root?.className);
- const containerProps = { ...(slotProps?.root || {}), className: containerClassName };
+ const containerProps = { ...(slotProps?.root || {}), className: classnames(styles.calendar, slotProps?.root?.className) };
const ContainerSlot = slots?.root || 'div';
return {children};
diff --git a/src/components/Empty.tsx b/src/components/Empty.tsx
index 3e57f09..ff9dee8 100644
--- a/src/components/Empty.tsx
+++ b/src/components/Empty.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { memo } from 'react';
import classnames from '../utils/classnames';
import styles from './styles.less';
import { SlotComponentProps } from '../types';
@@ -14,17 +14,19 @@ export type EmptyPrivateProps = {
};
};
-const Empty = ({ slots, slotProps }: EmptyPrivateProps): JSX.Element => {
- const rootClassName = classnames(styles.empty, slotProps?.root?.className);
- const { label = 'There is no date range to display', ...restProps } = slotProps?.root || {};
- const rootProps = { ...restProps, ...(slots?.root ? { label } : {}), className: rootClassName };
- const RootSlot = slots?.root || 'div';
+const Empty = memo(
+ ({ slots, slotProps }: EmptyPrivateProps): JSX.Element => {
+ const rootClassName = classnames(styles.empty, slotProps?.root?.className);
+ const { label = 'There is no date range to display', ...restProps } = slotProps?.root || {};
+ const rootProps = { ...restProps, ...(slots?.root ? { label } : {}), className: rootClassName };
+ const RootSlot = slots?.root || 'div';
- return (
-
- {label}
-
- );
-};
+ return (
+
+ {label}
+
+ );
+ },
+);
export default Empty;
diff --git a/src/index.tsx b/src/index.tsx
index 994a259..d8d4063 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,6 +1,6 @@
-import React, { useCallback, useMemo, useState } from 'react';
+import React, { useCallback, useMemo, useState, memo } from 'react';
import { getCalendarBaseAttributes } from './helpers';
-import { CalendarTuple, VisibilityMatrix, WeekdayIndex } from './types';
+import { CalendarTuple, VisibilityMatrix, WeekdayIndex, HeaderCellData, BodyCellData } from './types';
import Container, { ContainerProps } from './components/Container';
import Header, { HeaderProps, HeaderCellContentProps, HeaderCellProps } from './components/Header';
import Body, { BodyProps } from './components/Body';
@@ -9,7 +9,18 @@ import { BodyCellProps } from './components/BodyCell';
import { BodyCellContentProps } from './components/BodyCellContent';
import Empty, { EmptyProps } from './components/Empty';
-export type { ContainerProps, HeaderProps, HeaderCellProps, HeaderCellContentProps, BodyProps, BodyRowProps, BodyCellProps, BodyCellContentProps };
+export type {
+ ContainerProps,
+ HeaderProps,
+ HeaderCellProps,
+ HeaderCellContentProps,
+ BodyProps,
+ BodyRowProps,
+ BodyCellProps,
+ BodyCellContentProps,
+ HeaderCellData,
+ BodyCellData,
+};
type Slots = {
root?: React.ElementType;
@@ -47,61 +58,63 @@ export type IntervalCalendarProps = {
slotProps?: SlotProps;
};
-const IntervalCalendar = ({
- start = undefined,
- end = undefined,
- locale = 'default',
- numberOfRowsFirstRender = 8,
- numberOfRowsPreRender = 4,
- startRenderOnCurrentWeek = false,
- weekStartsOn = 0,
- slots,
- slotProps,
-}: IntervalCalendarProps): JSX.Element => {
- const [startDate, , numberOfWeeks, numberOfTodayWeek] = useMemo(() => getCalendarBaseAttributes(start, end, weekStartsOn), [start, end, weekStartsOn]);
+const IntervalCalendar = memo(
+ ({
+ start = undefined,
+ end = undefined,
+ locale = 'default',
+ numberOfRowsFirstRender = 8,
+ numberOfRowsPreRender = 4,
+ startRenderOnCurrentWeek = false,
+ weekStartsOn = 0,
+ slots,
+ slotProps,
+ }: IntervalCalendarProps): JSX.Element => {
+ const [startDate, , numberOfWeeks, numberOfTodayWeek] = useMemo(() => getCalendarBaseAttributes(start, end, weekStartsOn), [start, end, weekStartsOn]);
- const [visibilityMatrix, setVisibilityMatrix] = useState(
- Array(startRenderOnCurrentWeek ? numberOfTodayWeek + numberOfRowsFirstRender : numberOfRowsFirstRender)
- .fill(null)
- .reduce((acc: VisibilityMatrix, _, week) => ({ ...acc, [week]: startRenderOnCurrentWeek ? !(week < numberOfTodayWeek) : true }), {}),
- );
+ const [visibilityMatrix, setVisibilityMatrix] = useState(
+ Array(startRenderOnCurrentWeek ? numberOfTodayWeek + numberOfRowsFirstRender : numberOfRowsFirstRender)
+ .fill(null)
+ .reduce((acc: VisibilityMatrix, _, week) => ({ ...acc, [week]: startRenderOnCurrentWeek ? !(week < numberOfTodayWeek) : true }), {}),
+ );
- const handleVisibilityMatrixChange = useCallback(
- (week: number) => {
- setVisibilityMatrix(prevState => ({
- ...prevState,
- [week]: true,
- }));
- },
- [setVisibilityMatrix],
- );
+ const handleVisibilityMatrixChange = useCallback(
+ (week: number) => {
+ setVisibilityMatrix(prevState => ({
+ ...prevState,
+ [week]: true,
+ }));
+ },
+ [setVisibilityMatrix],
+ );
- return (
-
-
- {!!numberOfWeeks && !!startDate ? (
-
+
- ) : (
-
- )}
-
- );
-};
+ {!!numberOfWeeks && !!startDate ? (
+
+ ) : (
+
+ )}
+
+ );
+ },
+);
export default IntervalCalendar;