Skip to content

Commit

Permalink
feat(calendar): round borders (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
domhhv authored Oct 25, 2024
1 parent 73f707a commit d9a8769
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 46 deletions.
15 changes: 14 additions & 1 deletion src/components/calendar/CalendarCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import React from 'react';

import OccurrenceChip from './OccurrenceChip';

export type CellPosition =
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right'
| '';

type CalendarCellProps = {
dateNumber: number;
monthNumber: number;
Expand All @@ -17,6 +24,7 @@ type CalendarCellProps = {
onNavigateBack?: () => void;
onNavigateForward?: () => void;
rangeStatus: 'below-range' | 'in-range' | 'above-range';
position: CellPosition;
};

const CalendarCell = ({
Expand All @@ -27,6 +35,7 @@ const CalendarCell = ({
onNavigateForward,
onClick,
rangeStatus,
position,
}: CalendarCellProps) => {
const cellRef = React.useRef<HTMLDivElement>(null);
const user = useUser();
Expand Down Expand Up @@ -121,12 +130,16 @@ const CalendarCell = ({
'flex h-28 flex-1 flex-col border-r-2 border-neutral-500 last-of-type:border-r-0 hover:bg-neutral-200 dark:border-neutral-400 dark:hover:bg-neutral-800',
rangeStatus === 'below-range' && 'cursor-w-resize',
rangeStatus === 'above-range' && 'cursor-e-resize',
position === 'top-left' && 'rounded-tl-md',
position === 'top-right' && 'rounded-tr-md',
position === 'bottom-left' && 'rounded-bl-md',
position === 'bottom-right' && 'rounded-br-md',
isToday &&
'bg-neutral-200 hover:bg-neutral-300 dark:bg-neutral-800 dark:hover:bg-neutral-700'
);

const cellHeaderClassName = clsx(
'flex items-center justify-between rounded-t px-1 py-0.5',
'flex items-center justify-between rounded-t px-1.5 py-0.5',
rangeStatus !== 'in-range' && 'text-neutral-400 dark:text-neutral-600'
);

Expand Down
14 changes: 7 additions & 7 deletions src/components/calendar/CalendarHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ const CalendarHeader = ({

return (
<div className="mb-2 flex flex-col items-center justify-between gap-2 md:flex-row md:gap-0">
<div className="flex flex-col items-center justify-between gap-2 md:flex-row md:gap-0">
<div className="flex flex-col items-center justify-between gap-2 md:flex-row md:gap-2">
<div className="mr-2 flex flex-col items-center gap-2 md:flex-row">
<Select
variant="bordered"
variant="flat"
selectedKeys={new Set([activeMonthLabel])}
onChange={handleMonthChange}
className="w-[250px]"
Expand All @@ -103,7 +103,7 @@ const CalendarHeader = ({
))}
</Select>
<Select
variant="bordered"
variant="flat"
selectedKeys={new Set([activeYear])}
onChange={handleYearChange}
>
Expand All @@ -112,7 +112,7 @@ const CalendarHeader = ({
))}
</Select>
</div>
<div className="flex items-center">
<div className="flex items-center gap-2">
<Button
isIconOnly
variant="light"
Expand All @@ -123,7 +123,7 @@ const CalendarHeader = ({
>
<ArrowFatLeft size="20" />
</Button>
<Button variant="light" onClick={onResetFocusedDate}>
<Button variant="bordered" onClick={onResetFocusedDate}>
Today
</Button>
<Button
Expand All @@ -141,7 +141,7 @@ const CalendarHeader = ({
{shouldRenderFilters && (
<div className="flex flex-col items-center justify-between gap-2 md:flex-row">
<Select
variant="bordered"
variant="flat"
label={screenSize < 1280 ? null : 'Filter by habits'}
selectedKeys={filteredBy.habitIds}
onChange={handleHabitsFilterChange}
Expand All @@ -159,7 +159,7 @@ const CalendarHeader = ({
))}
</Select>
<Select
variant="bordered"
variant="flat"
label={screenSize < 1280 ? null : 'Filter by traits'}
selectedKeys={filteredBy.traitIds}
onChange={handleTraitsFilterChange}
Expand Down
105 changes: 67 additions & 38 deletions src/components/calendar/CalendarMonthGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type CalendarDate, getWeeksInMonth } from '@internationalized/date';
import clsx from 'clsx';
import React, { type ForwardedRef } from 'react';
import { useLocale } from 'react-aria';
import { type CalendarState } from 'react-stately';
Expand All @@ -23,46 +24,74 @@ const Month = (
const weekIndexes = [...new Array(weeksInMonthCount).keys()];
const { month: activeMonth } = state.visibleRange.start;

const getCellPosition = (weekIndex: number, dayIndex: number) => {
if (weekIndex === 0 && dayIndex === 0) {
return 'top-left';
}

if (weekIndex === 0 && dayIndex === 6) {
return 'top-right';
}

if (weekIndex === weeksInMonthCount - 1 && dayIndex === 0) {
return 'bottom-left';
}

if (weekIndex === weeksInMonthCount - 1 && dayIndex === 6) {
return 'bottom-right';
}

return '';
};

return (
<div ref={ref} className="flex flex-1 flex-col">
{weekIndexes.map((weekIndex) => (
<div
key={weekIndex}
className="flex h-[110px] justify-between border-l-2 border-r-2 border-t-2 border-neutral-500 last-of-type:border-b-2 dark:border-neutral-400 lg:h-auto"
>
{state
.getDatesInWeek(weekIndex)
.map((calendarDate: CalendarDate | null) => {
if (!calendarDate) {
return null;
}

const { month, day, year } = calendarDate;

const rangeStatus =
month < activeMonth
? 'below-range'
: month > activeMonth
? 'above-range'
: 'in-range';

const [dayKey] = calendarDate.toString().split('T');

return (
<CalendarCell
key={dayKey}
dateNumber={day}
monthNumber={month}
fullYear={year}
onClick={onDayModalDialogOpen}
rangeStatus={rangeStatus}
onNavigateBack={state.focusPreviousPage}
onNavigateForward={state.focusNextPage}
/>
);
})}
</div>
))}
{weekIndexes.map((weekIndex) => {
const weekContainerClassName = clsx(
'flex h-[110px] justify-between border-l-2 border-r-2 border-t-2 border-neutral-500 last-of-type:border-b-2 dark:border-neutral-400 lg:h-auto',
weekIndex === 0 && 'rounded-t-lg',
weekIndex === weeksInMonthCount - 1 && 'rounded-b-lg'
);

return (
<div key={weekIndex} className={weekContainerClassName}>
{state
.getDatesInWeek(weekIndex)
.map((calendarDate: CalendarDate | null, dayIndex) => {
if (!calendarDate) {
return null;
}

const { month, day, year } = calendarDate;

const rangeStatus =
month < activeMonth
? 'below-range'
: month > activeMonth
? 'above-range'
: 'in-range';

const [dayKey] = calendarDate.toString().split('T');

const position = getCellPosition(weekIndex, dayIndex);

return (
<CalendarCell
key={dayKey}
dateNumber={day}
monthNumber={month}
fullYear={year}
onClick={onDayModalDialogOpen}
rangeStatus={rangeStatus}
position={position}
onNavigateBack={state.focusPreviousPage}
onNavigateForward={state.focusNextPage}
/>
);
})}
</div>
);
})}
</div>
);
};
Expand Down

0 comments on commit d9a8769

Please sign in to comment.