Skip to content

Commit

Permalink
Add support for showNeighboringCentury and showNeighboringDecade props
Browse files Browse the repository at this point in the history
  • Loading branch information
wojtekmaj committed Jan 9, 2024
1 parent 176d6e6 commit 695497e
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 13 deletions.
2 changes: 2 additions & 0 deletions packages/react-calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ Displays a complete, interactive calendar.
| showDoubleView | Whether to show two months/years/… at a time instead of one. Defaults `showFixedNumberOfWeeks` prop to be `true`. | `false` | `true` |
| showFixedNumberOfWeeks | Whether to always show fixed number of weeks (6). Forces `showNeighboringMonth` prop to be `true`. | `false` | `true` |
| showNavigation | Whether a navigation bar with arrows and title shall be rendered. | `true` | `false` |
| showNeighboringCentury | Whether decades from next century shall be rendered to fill the entire last row in. | `false` | `true` |
| showNeighboringDecade | Whether years from next decade shall be rendered to fill the entire last row in. | `false` | `true` |
| showNeighboringMonth | Whether days from previous or next month shall be rendered if the month doesn't start on the first day of the week or doesn't end on the last day of the week, respectively. | `true` | `false` |
| showWeekNumbers | Whether week numbers shall be shown at the left of MonthView or not. | `false` | `true` |
| tileClassName | Class name(s) that will be applied to a given calendar item (day on month view, month on year view and so on). | n/a | <ul><li>String: `"class1 class2"`</li><li>Array of strings: `["class1", "class2 class3"]`</li><li>Function: `({ activeStartDate, date, view }) => view === 'month' && date.getDay() === 3 ? 'wednesday' : null`</li></ul> |
Expand Down
4 changes: 3 additions & 1 deletion packages/react-calendar/src/Calendar.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@
color: #d10000;
}

.react-calendar__month-view__days__day--neighboringMonth {
.react-calendar__month-view__days__day--neighboringMonth,
.react-calendar__decade-view__years__year--neighboringDecade,
.react-calendar__century-view__decades__decade--neighboringCentury {
color: #757575;
}

Expand Down
30 changes: 30 additions & 0 deletions packages/react-calendar/src/Calendar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,36 @@ describe('Calendar', () => {
expect(firstDayTileTimeAbbr).toHaveAccessibleName(format(new Date(2016, 11, 26)));
});

it('passes showNeighboringDecade flag to DecadeView component given showNeighboringDecade flag', () => {
const activeStartDate = new Date(2001, 0, 1);

const { container } = render(
<Calendar activeStartDate={activeStartDate} showNeighboringDecade view="decade" />,
);

const lastYearTile = container.querySelector(
'.react-calendar__tile:last-child',
) as HTMLDivElement;

// The last year that this calendar should show is 2029.
expect(lastYearTile).toHaveAccessibleName('2012');
});

it('passes showNeighboringCentury flag to CenturyView component given showNeighboringCentury flag', () => {
const activeStartDate = new Date(2001, 0, 1);

const { container } = render(
<Calendar activeStartDate={activeStartDate} showNeighboringCentury view="century" />,
);

const lastDecadeTile = container.querySelector(
'.react-calendar__tile:last-child',
) as HTMLDivElement;

// The last decade that this calendar should show is 2111 – 2120.
expect(lastDecadeTile).toHaveAccessibleName('2111 – 2120');
});

describe('displays initial view properly', () => {
it('displays a view with a given value when defaultValue is given', () => {
const defaultValue = new Date(2017, 0, 15);
Expand Down
34 changes: 32 additions & 2 deletions packages/react-calendar/src/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,20 @@ export type CalendarProps = {
* @example false
*/
showNavigation?: boolean;
/**
* Whether decades from next century shall be rendered to fill the entire last row in.
*
* @default false
* @example true
*/
showNeighboringCentury?: boolean;
/**
* Whether years from next decade shall be rendered to fill the entire last row in.
*
* @default false
* @example true
*/
showNeighboringDecade?: boolean;
/**
* Whether days from previous or next month shall be rendered if the month doesn't start on the first day of the week or doesn't end on the last day of the week, respectively.
*
Expand Down Expand Up @@ -643,6 +657,8 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) {
showDoubleView,
showFixedNumberOfWeeks,
showNavigation = true,
showNeighboringCentury,
showNeighboringDecade,
showNeighboringMonth = true,
showWeekNumbers,
tileClassName,
Expand Down Expand Up @@ -1022,10 +1038,22 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) {

switch (view) {
case 'century': {
return <CenturyView formatYear={formatYear} {...commonProps} />;
return (
<CenturyView
formatYear={formatYear}
showNeighboringCentury={showNeighboringCentury}
{...commonProps}
/>
);
}
case 'decade': {
return <DecadeView formatYear={formatYear} {...commonProps} />;
return (
<DecadeView
formatYear={formatYear}
showNeighboringDecade={showNeighboringDecade}
{...commonProps}
/>
);
}
case 'year': {
return (
Expand Down Expand Up @@ -1170,6 +1198,8 @@ Calendar.propTypes = {
showDoubleView: PropTypes.bool,
showFixedNumberOfWeeks: PropTypes.bool,
showNavigation: PropTypes.bool,
showNeighboringCentury: PropTypes.bool,
showNeighboringDecade: PropTypes.bool,
showNeighboringMonth: PropTypes.bool,
showWeekNumbers: PropTypes.bool,
tileClassName: PropTypes.oneOfType([PropTypes.func, isClassName]),
Expand Down
2 changes: 2 additions & 0 deletions packages/react-calendar/src/CenturyView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';

import Decades from './CenturyView/Decades.js';

Expand All @@ -19,6 +20,7 @@ const CenturyView: React.FC<CenturyViewProps> = function CenturyView(props) {

CenturyView.propTypes = {
...tileGroupProps,
showNeighboringCentury: PropTypes.bool,
};

export default CenturyView;
1 change: 1 addition & 0 deletions packages/react-calendar/src/CenturyView/Decade.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Decade from './Decade.js';
const tileProps = {
activeStartDate: new Date(2018, 0, 1),
classes: ['react-calendar__tile'],
currentCentury: 2001,
date: new Date(2011, 0, 1),
};

Expand Down
20 changes: 18 additions & 2 deletions packages/react-calendar/src/CenturyView/Decade.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { getDecadeStart, getDecadeEnd } from '@wojtekmaj/date-utils';
import { getDecadeStart, getDecadeEnd, getCenturyStart } from '@wojtekmaj/date-utils';

import Tile from '../Tile.js';

Expand All @@ -10,6 +10,7 @@ const className = 'react-calendar__century-view__decades__decade';

type DecadeProps = {
classes?: string[];
currentCentury: number;
/**
* Function called to override default formatting of year in the top navigation section. Can be used to use your own formatting function.
*
Expand All @@ -23,15 +24,30 @@ type DecadeProps = {

export default function Decade({
classes = [],
currentCentury,
formatYear = defaultFormatYear,
...otherProps
}: DecadeProps) {
const { date, locale } = otherProps;

const classesProps: string[] = [];

if (classes) {
classesProps.push(...classes);
}

if (className) {
classesProps.push(className);
}

if (getCenturyStart(date).getFullYear() !== currentCentury) {
classesProps.push(`${className}--neighboringCentury`);
}

return (
<Tile
{...otherProps}
classes={[...classes, className]}
classes={classesProps}
maxDateTransform={getDecadeEnd}
minDateTransform={getDecadeStart}
view="century"
Expand Down
14 changes: 11 additions & 3 deletions packages/react-calendar/src/CenturyView/Decades.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ type DecadesProps = {
* @example new Date(2017, 0, 1)
*/
activeStartDate: Date;
/**
* Whether decades from next century shall be rendered to fill the entire last row in.
*
* @default false
* @example true
*/
showNeighboringCentury?: boolean;
} & Omit<
React.ComponentProps<typeof TileGroup>,
'dateTransform' | 'dateType' | 'end' | 'renderTile' | 'start'
> &
Omit<React.ComponentProps<typeof Decade>, 'classes' | 'date'>;
Omit<React.ComponentProps<typeof Decade>, 'classes' | 'currentCentury' | 'date'>;

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

return (
<TileGroup
Expand All @@ -37,6 +44,7 @@ export default function Decades(props: DecadesProps) {
{...otherProps}
{...otherTileProps}
activeStartDate={activeStartDate}
currentCentury={start}
date={date}
/>
)}
Expand Down
2 changes: 2 additions & 0 deletions packages/react-calendar/src/DecadeView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';

import Years from './DecadeView/Years.js';

Expand All @@ -19,6 +20,7 @@ const DecadeView: React.FC<DecadeViewProps> = function DecadeView(props) {

DecadeView.propTypes = {
...tileGroupProps,
showNeighboringDecade: PropTypes.bool,
};

export default DecadeView;
1 change: 1 addition & 0 deletions packages/react-calendar/src/DecadeView/Year.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Year from './Year.js';
const tileProps = {
activeStartDate: new Date(2018, 0, 1),
classes: ['react-calendar__tile'],
currentDecade: 2011,
date: new Date(2018, 0, 1),
};

Expand Down
20 changes: 18 additions & 2 deletions packages/react-calendar/src/DecadeView/Year.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { getYearStart, getYearEnd } from '@wojtekmaj/date-utils';
import { getYearStart, getYearEnd, getDecadeStart } from '@wojtekmaj/date-utils';

import Tile from '../Tile.js';

Expand All @@ -9,6 +9,7 @@ const className = 'react-calendar__decade-view__years__year';

type YearProps = {
classes?: string[];
currentDecade: number;
/**
* Function called to override default formatting of year in the top navigation section. Can be used to use your own formatting function.
*
Expand All @@ -22,15 +23,30 @@ type YearProps = {

export default function Year({
classes = [],
currentDecade,
formatYear = defaultFormatYear,
...otherProps
}: YearProps) {
const { date, locale } = otherProps;

const classesProps: string[] = [];

if (classes) {
classesProps.push(...classes);
}

if (className) {
classesProps.push(className);
}

if (getDecadeStart(date).getFullYear() !== currentDecade) {
classesProps.push(`${className}--neighboringDecade`);
}

return (
<Tile
{...otherProps}
classes={[...classes, className]}
classes={classesProps}
maxDateTransform={getYearEnd}
minDateTransform={getYearStart}
view="decade"
Expand Down
14 changes: 11 additions & 3 deletions packages/react-calendar/src/DecadeView/Years.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ type YearsProps = {
* @example new Date(2017, 0, 1)
*/
activeStartDate: Date;
/**
* Whether years from next decade shall be rendered to fill the entire last row in.
*
* @default false
* @example true
*/
showNeighboringDecade?: boolean;
} & Omit<
React.ComponentProps<typeof TileGroup>,
'dateTransform' | 'dateType' | 'end' | 'renderTile' | 'start'
> &
Omit<React.ComponentProps<typeof Year>, 'classes' | 'date'>;
Omit<React.ComponentProps<typeof Year>, 'classes' | 'currentDecade' | 'date'>;

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

return (
<TileGroup
Expand All @@ -37,6 +44,7 @@ export default function Years(props: YearsProps) {
{...otherProps}
{...otherTileProps}
activeStartDate={activeStartDate}
currentDecade={start}
date={date}
/>
)}
Expand Down
8 changes: 8 additions & 0 deletions test/Test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export default function Test() {
const [selectRange, setSelectRange] = useState(false);
const [showDoubleView, setShowDoubleView] = useState(false);
const [showFixedNumberOfWeeks, setShowFixedNumberOfWeeks] = useState(false);
const [showNeighboringCentury, setShowNeighboringCentury] = useState(false);
const [showNeighboringDecade, setShowNeighboringDecade] = useState(false);
const [showNeighboringMonth, setShowNeighboringMonth] = useState(true);
const [showWeekNumbers, setShowWeekNumbers] = useState(false);
const [value, setValue] = useState<LooseValue>(now);
Expand Down Expand Up @@ -153,6 +155,8 @@ export default function Test() {
selectRange,
showDoubleView,
showFixedNumberOfWeeks,
showNeighboringCentury,
showNeighboringDecade,
showNeighboringMonth,
showWeekNumbers,
tileClassName,
Expand Down Expand Up @@ -192,10 +196,14 @@ export default function Test() {
<ViewOptions
setShowDoubleView={setShowDoubleView}
setShowFixedNumberOfWeeks={setShowFixedNumberOfWeeks}
setShowNeighboringCentury={setShowNeighboringCentury}
setShowNeighboringDecade={setShowNeighboringDecade}
setShowNeighboringMonth={setShowNeighboringMonth}
setShowWeekNumbers={setShowWeekNumbers}
showDoubleView={showDoubleView}
showFixedNumberOfWeeks={showFixedNumberOfWeeks}
showNeighboringCentury={showNeighboringCentury}
showNeighboringDecade={showNeighboringDecade}
showNeighboringMonth={showNeighboringMonth}
showWeekNumbers={showWeekNumbers}
/>
Expand Down
Loading

0 comments on commit 695497e

Please sign in to comment.