Skip to content

Commit

Permalink
refactor calendar range to be part of calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
steppy452 committed Feb 15, 2024
1 parent 0ca0801 commit f2d42eb
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 298 deletions.
9 changes: 5 additions & 4 deletions src/form/Calendar/Calendar.story.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState } from 'react';
import { Card } from '../../layout/Card';
import { Calendar } from './Calendar';
import { CalendarRange } from './CalendarRange';
import { add, addMonths, sub } from 'date-fns';
import { Divider, Stack } from '../../layout';

Expand Down Expand Up @@ -119,11 +118,13 @@ export const Multiview = () => {

return (
<Card>
<CalendarRange
<Calendar
value={range}
onChange={val => setRange(val as [Date, Date])}
numMonths={3}
enableDayOfWeek
numMonths={2}
direction="past"
max="now"
showDayOfWeek
isRange
/>
<Divider />
Expand Down
61 changes: 53 additions & 8 deletions src/form/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { FC, useCallback, useMemo, useState } from 'react';
import { Button } from '../../elements/Button';
import {
add,
addMonths,
addYears,
endOfDecade,
getMonth,
Expand All @@ -19,6 +20,7 @@ import {
import { DateFormat } from '../../data/DateFormat';
import { CalendarDays } from './CalendarDays';
import { CalendarMonths } from './CalendarMonths';
import { CalendarRange } from './CalendarRange';
import { CalendarYears } from './CalendarYears';
import { SmallHeading } from '../../typography';

Expand Down Expand Up @@ -63,6 +65,16 @@ export interface CalendarProps {
*/
previousArrow?: React.ReactNode | string;

/**
* The number of calendar months to display.
*/
numMonths?: number;

/**
* Defaults view to show past or future months if multiple months shown.
*/
direction?: 'past' | 'future';

/**
* The date format to use for the calendar. Defaults 'MMMM yyyy'.
*/
Expand All @@ -71,7 +83,7 @@ export interface CalendarProps {
/**
* Whether to display day of week labels
*/
enableDayOfWeek?: boolean;
showDayOfWeek?: boolean;

/**
* Whether to animate the calendar.
Expand All @@ -95,9 +107,12 @@ export const Calendar: FC<CalendarProps> = ({
value,
disabled,
isRange,
numMonths,
direction,
previousArrow,
nextArrow,
dateFormat,
showDayOfWeek,
animated,
onChange,
onViewChange
Expand Down Expand Up @@ -125,6 +140,12 @@ export const Calendar: FC<CalendarProps> = ({
'forward' | 'back' | null
>(null);

const displayMonths = Array.from(Array(numMonths).keys());
const showPast = direction === 'past';
if (showPast) {
displayMonths.reverse();
}

const previousClickHandler = useCallback(() => {
setScrollDirection('back');
if (view === 'days') {
Expand Down Expand Up @@ -225,11 +246,16 @@ export const Calendar: FC<CalendarProps> = ({
>
<SmallHeading disableMargins>
{view === 'days' && (
<DateFormat
date={viewValue}
format={dateFormat}
allowToggle={false}
/>
<div className={css.multiviewLabel}>
{displayMonths.map(i => (
<DateFormat
key={`label-${i}`}
date={addMonths(viewValue, showPast ? -i : i)}
format={dateFormat}
allowToggle={false}
/>
))}
</div>
)}
{view === 'months' && <>{yearValue}</>}
{view === 'years' && (
Expand Down Expand Up @@ -260,14 +286,31 @@ export const Calendar: FC<CalendarProps> = ({
scale: { type: animated ? 'tween' : false }
}}
>
{view === 'days' && (
{view === 'days' && numMonths === 1 && (
<CalendarDays
value={viewValue}
min={min}
max={max}
disabled={disabled}
isRange={isRange}
current={isRange ? [rangeStart, rangeEnd] : date}
showDayOfWeek={showDayOfWeek}
xAnimation={xAnimation}
animated={animated}
onChange={dateChangeHandler}
/>
)}
{view === 'days' && numMonths !== 1 && (
<CalendarRange
value={viewValue}
min={min}
max={max}
disabled={disabled}
isRange={isRange}
numMonths={numMonths}
direction={direction}
current={isRange ? [rangeStart, rangeEnd] : date}
showDayOfWeek={showDayOfWeek}
xAnimation={xAnimation}
animated={animated}
onChange={dateChangeHandler}
Expand Down Expand Up @@ -301,5 +344,7 @@ Calendar.defaultProps = {
nextArrow: '→',
animated: true,
dateFormat: 'MMMM yyyy',
range: [new Date(), new Date()]
range: [new Date(), new Date()],
numMonths: 1,
direction: 'future'
};
37 changes: 29 additions & 8 deletions src/form/Calendar/CalendarDays/CalendarDays.module.css
Original file line number Diff line number Diff line change
@@ -1,36 +1,55 @@
.week {
--button-border-radius: var(--calendar-day-radius);
--button-color: var(--calendar-day-color);

display: grid;
grid-template-columns: repeat(7, 1fr);
gap: var(--calendar-gap);
margin-bottom: var(--calendar-gap);

.day {
flex: 1;
transition: border 100ms ease-in-out;
padding: var(--calendar-spacing);
text-align: center;

&:not(:disabled) {
background: var(--calendar-day-background);
}

&:hover:not(:disabled) {
border-color: var(--calendar-day-border-hover);
}

&:not(.range).outside {
opacity: 0.6;
color: color-mix(in srgb, var(--button-color) 60%, transparent);
}

&.range,
&.rangeHover {
&.range {
border-radius: 0;
/* !important to override default button styling */
background: var(--calendar-day-background-selected) !important;
border-color: var(--calendar-day-border-selected) !important;

&:hover {
border-color: var(--calendar-day-border-hover) !important;
}
}

&.startRangeDate {
border-top-left-radius: var(--button-border-radius);
border-top-left-radius: var(--calendar-day-radius);
}

&.roundStartDateBottom {
border-bottom-left-radius: var(--button-border-radius);
border-bottom-left-radius: var(--calendar-day-radius);
}

&.endRangeDate {
border-bottom-right-radius: var(--button-border-radius);
border-bottom-right-radius: var(--calendar-day-radius);
}

&.roundEndDateTop {
border-top-right-radius: var(--button-border-radius);
border-top-right-radius: var(--calendar-day-radius);
}

&.hideDay {
Expand All @@ -44,9 +63,11 @@
grid-template-columns: repeat(7, 1fr);
gap: var(--spacing-sm);
width: 100%;
margin: var(--spacing-md) 0 var(--spacing-sm);
padding: var(--spacing-md) 0;
border-top: 1px solid var(--slate-500);

.dayOfWeek {
text-align: center;
font-weight: var(--font-weight-bold);
}
}
6 changes: 3 additions & 3 deletions src/form/Calendar/CalendarDays/CalendarDays.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export interface CalendarDaysProps {
/**
* Whether to display day of week labels
*/
enableDayOfWeek?: boolean;
showDayOfWeek?: boolean;

/**
* Whether the calendar is a range picker.
Expand Down Expand Up @@ -112,7 +112,7 @@ export const CalendarDays: FC<CalendarDaysProps> = ({
max,
animated,
xAnimation = 0,
enableDayOfWeek,
showDayOfWeek,
hidePrevMonthDays,
hideNextMonthDays,
onChange,
Expand Down Expand Up @@ -254,7 +254,7 @@ export const CalendarDays: FC<CalendarDaysProps> = ({
opacity: { duration: 0.2, type: animated ? 'tween' : false }
}}
>
{enableDayOfWeek && (
{showDayOfWeek && (
<div className={css.weekLabels}>
{DAY_OF_WEEK_LABELS.map(day => (
<div key={`day-${day}`} className={css.dayOfWeek}>
Expand Down
Loading

0 comments on commit f2d42eb

Please sign in to comment.