Skip to content

Commit

Permalink
Refactor TileGroup to accept render function, not ElementType
Browse files Browse the repository at this point in the history
  • Loading branch information
wojtekmaj committed Jul 26, 2023
1 parent ec4bd3a commit 1a4bd94
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 50 deletions.
25 changes: 18 additions & 7 deletions src/CenturyView/Decades.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,39 @@ import Decade from './Decade';

import { getBeginOfCenturyYear } from '../shared/dates';

import type { RangeType } from '../shared/types';

type DecadesProps = {
activeStartDate: Date;
valueType: RangeType;
} & Omit<React.ComponentProps<typeof Decade>, 'classes' | 'date'>;
} & Omit<
React.ComponentProps<typeof TileGroup>,
'dateTransform' | 'dateType' | 'end' | 'renderTile' | 'start'
> &
Omit<React.ComponentProps<typeof Decade>, 'classes' | 'date'>;

export default function Decades(props: DecadesProps) {
const { activeStartDate } = props;
const { activeStartDate, hover, value, valueType, ...otherProps } = props;
const start = getBeginOfCenturyYear(activeStartDate);
const end = start + 99;

return (
<TileGroup
{...props}
className="react-calendar__century-view__decades"
dateTransform={getDecadeStart}
dateType="decade"
end={end}
hover={hover}
renderTile={({ date, ...otherTileProps }) => (
<Decade
key={date.getTime()}
{...otherProps}
{...otherTileProps}
activeStartDate={activeStartDate}
date={date}
/>
)}
start={start}
step={10}
tile={Decade}
value={value}
valueType={valueType}
/>
);
}
25 changes: 18 additions & 7 deletions src/DecadeView/Years.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,38 @@ import Year from './Year';

import { getBeginOfDecadeYear } from '../shared/dates';

import type { RangeType } from '../shared/types';

type YearsProps = {
activeStartDate: Date;
valueType: RangeType;
} & Omit<React.ComponentProps<typeof Year>, 'classes' | 'date'>;
} & Omit<
React.ComponentProps<typeof TileGroup>,
'dateTransform' | 'dateType' | 'end' | 'renderTile' | 'start'
> &
Omit<React.ComponentProps<typeof Year>, 'classes' | 'date'>;

export default function Years(props: YearsProps) {
const { activeStartDate } = props;
const { activeStartDate, hover, value, valueType, ...otherProps } = props;
const start = getBeginOfDecadeYear(activeStartDate);
const end = start + 9;

return (
<TileGroup
{...props}
className="react-calendar__decade-view__years"
dateTransform={getYearStart}
dateType="year"
end={end}
hover={hover}
renderTile={({ date, ...otherTileProps }) => (
<Year
key={date.getTime()}
{...otherProps}
{...otherTileProps}
activeStartDate={activeStartDate}
date={date}
/>
)}
start={start}
tile={Year}
value={value}
valueType={valueType}
/>
);
}
37 changes: 29 additions & 8 deletions src/MonthView/Days.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,30 @@ import Day from './Day';
import { getDayOfWeek } from '../shared/dates';
import { mapCalendarType } from '../shared/utils';

import type { CalendarType, DeprecatedCalendarType, RangeType } from '../shared/types';
import type { CalendarType, DeprecatedCalendarType } from '../shared/types';

type DaysProps = {
activeStartDate: Date;
calendarType?: CalendarType | DeprecatedCalendarType;
showFixedNumberOfWeeks?: boolean;
showNeighboringMonth?: boolean;
valueType: RangeType;
} & Omit<React.ComponentProps<typeof Day>, 'classes' | 'currentMonthIndex' | 'date' | 'point'>;
} & Omit<
React.ComponentProps<typeof TileGroup>,
'dateTransform' | 'dateType' | 'end' | 'renderTile' | 'start'
> &
Omit<React.ComponentProps<typeof Day>, 'classes' | 'currentMonthIndex' | 'date' | 'point'>;

export default function Days(props: DaysProps) {
const { activeStartDate, calendarType: calendarTypeOrDeprecatedCalendarType } = props;
const { showFixedNumberOfWeeks, showNeighboringMonth, ...otherProps } = props;
const {
activeStartDate,
calendarType: calendarTypeOrDeprecatedCalendarType,
hover,
showFixedNumberOfWeeks,
showNeighboringMonth,
value,
valueType,
...otherProps
} = props;

const calendarType = mapCalendarType(calendarTypeOrDeprecatedCalendarType);
const year = getYear(activeStartDate);
Expand Down Expand Up @@ -63,20 +74,30 @@ export default function Days(props: DaysProps) {

return (
<TileGroup
{...otherProps}
className="react-calendar__month-view__days"
count={7}
currentMonthIndex={monthIndex}
dateTransform={(day) => {
const date = new Date();
date.setFullYear(year, monthIndex, day);
return getDayStart(date);
}}
dateType="day"
hover={hover}
end={end}
renderTile={({ date, ...otherTileProps }) => (
<Day
key={date.getTime()}
{...otherProps}
{...otherTileProps}
activeStartDate={activeStartDate}
currentMonthIndex={monthIndex}
date={date}
/>
)}
offset={offset}
start={start}
tile={Day}
value={value}
valueType={valueType}
/>
);
}
37 changes: 16 additions & 21 deletions src/TileGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,52 @@ import Flex from './Flex';

import { getTileClasses } from './shared/utils';

import type { Range, RangeType } from './shared/types';
import type { RangeType, Value } from './shared/types';

type TileGroupProps<T extends React.ElementType> = {
type TileGroupProps = {
className?: string;
count?: number;
dateTransform: (point: number) => Date;
dateType: RangeType;
end: number;
hover?: Date;
hover?: Date | null;
offset?: number;
renderTile: (props: { classes: string[]; date: Date }) => React.ReactElement;
start: number;
step?: number;
tile: T;
value?: Date | Range<Date>;
value?: Value;
valueType: RangeType;
} & Omit<React.ComponentProps<T>, 'classes' | 'date'>;
};

export default function TileGroup<T extends React.ElementType>({
export default function TileGroup({
className,
count = 3,
dateTransform,
dateType,
end,
hover,
offset,
renderTile,
start,
step = 1,
tile: Tile,
value,
valueType,
...tileProps
}: TileGroupProps<T>) {
}: TileGroupProps) {
const tiles = [];
for (let point = start; point <= end; point += step) {
const date = dateTransform(point);

const FixedTile = Tile as React.ElementType;

tiles.push(
<FixedTile
key={date.getTime()}
classes={getTileClasses({
value,
valueType,
renderTile({
classes: getTileClasses({
date,
dateType,
hover,
})}
date={date}
{...tileProps}
/>,
value,
valueType,
}),
date,
}),
);
}

Expand Down
25 changes: 18 additions & 7 deletions src/YearView/Months.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import { getMonthStart, getYear } from '@wojtekmaj/date-utils';
import TileGroup from '../TileGroup';
import Month from './Month';

import type { RangeType } from '../shared/types';

type MonthsProps = {
activeStartDate: Date;
valueType: RangeType;
} & Omit<React.ComponentProps<typeof Month>, 'classes' | 'date'>;
} & Omit<
React.ComponentProps<typeof TileGroup>,
'dateTransform' | 'dateType' | 'end' | 'renderTile' | 'start'
> &
Omit<React.ComponentProps<typeof Month>, 'classes' | 'date'>;

export default function Months(props: MonthsProps) {
const { activeStartDate } = props;
const { activeStartDate, hover, value, valueType, ...otherProps } = props;
const start = 0;
const end = 11;
const year = getYear(activeStartDate);

return (
<TileGroup
{...props}
className="react-calendar__year-view__months"
dateTransform={(monthIndex) => {
const date = new Date();
Expand All @@ -28,8 +28,19 @@ export default function Months(props: MonthsProps) {
}}
dateType="month"
end={end}
hover={hover}
renderTile={({ date, ...otherTileProps }) => (
<Month
key={date.getTime()}
{...otherProps}
{...otherTileProps}
activeStartDate={activeStartDate}
date={date}
/>
)}
start={start}
tile={Month}
value={value}
valueType={valueType}
/>
);
}

0 comments on commit 1a4bd94

Please sign in to comment.