diff --git a/docker-compose.yml b/docker-compose.yml index c42dcbc..07c03f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.9' services: - biblio-stats-react: + react: container_name: ${REVERSE_DOMAIN} image: "${DOCKER_IMAGE}" labels: diff --git a/src/App.tsx b/src/App.tsx index 9593eca..ab6a755 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { DateRangePicker } from './examples/DateRangePicker'; import { SingleMonth } from './examples/SingleMonth'; import { WeekView } from './examples/WeekView'; +import { DateRangeView } from './examples/DateRangeView'; import { CompactYear } from './examples/CompactYear'; import styles from './App.module.scss'; @@ -11,6 +12,7 @@ const App: React.FC = () => { + ); diff --git a/src/components/calendar/DateRange/DateRange.module.scss b/src/components/calendar/DateRange/DateRange.module.scss new file mode 100644 index 0000000..05bcc37 --- /dev/null +++ b/src/components/calendar/DateRange/DateRange.module.scss @@ -0,0 +1,46 @@ +@use '../shared/variables' as shared; +@use '../shared/colors' as colors; + +.DateRange { + &__Container { + display: flex; + flex-wrap: wrap; + gap: 0; + align-items: flex-start; + } + + &__DayWrapper { + padding: shared.$week-wrapper-padding; + + @media (min-width: shared.$breakpoint-tablet) { + padding: shared.$week-wrapper-padding-desktop; + } + + &--rangeStart:not(&--rangeEnd) { + padding: shared.$week-wrapper-padding 0 shared.$week-wrapper-padding shared.$week-wrapper-padding; + background-color: colors.$day-color-selected; + + @media (min-width: shared.$breakpoint-tablet) { + padding: shared.$week-wrapper-padding-desktop 0 shared.$week-wrapper-padding-desktop shared.$week-wrapper-padding-desktop; + } + } + + &--rangeEnd:not(&--rangeStart) { + padding: shared.$week-wrapper-padding shared.$week-wrapper-padding shared.$week-wrapper-padding 0; + background-color: colors.$day-color-selected; + + @media (min-width: shared.$breakpoint-tablet) { + padding: shared.$week-wrapper-padding-desktop shared.$week-wrapper-padding-desktop shared.$week-wrapper-padding-desktop 0; + } + } + + &--selected:not(&--rangeStart):not(&--rangeEnd) { + padding: shared.$week-wrapper-padding 0; + background-color: colors.$day-color-selected; + + @media (min-width: shared.$breakpoint-tablet) { + padding: shared.$week-wrapper-padding-desktop 0; + } + } + } +} \ No newline at end of file diff --git a/src/components/calendar/DateRange/index.tsx b/src/components/calendar/DateRange/index.tsx new file mode 100644 index 0000000..d3afe13 --- /dev/null +++ b/src/components/calendar/DateRange/index.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { eachDayOfInterval, startOfDay } from 'date-fns'; +import { Day } from '../Day'; +import { getDateVariations } from '../../../utils/dateUtils'; +import { HeaderStyle, DaySize } from '../../../types/calendar'; +import styles from './DateRange.module.scss'; +import classNames from 'classnames'; + +interface DateRangeProps { + from: Date; + to: Date; + included?: boolean; + headerStyle?: HeaderStyle; + weekendDays?: number[]; + size?: DaySize; + fontProportion?: number; + magnify?: boolean; +} + +export const DateRange: React.FC = ({ + from, + to, + included = true, + headerStyle = 'tiny', + weekendDays = [6, 0], + size = 'l', + fontProportion = 100, + magnify = false +}) => { + const startDate = startOfDay(from); + const endDate = startOfDay(to); + + const days = eachDayOfInterval({ start: startDate, end: endDate }); + + const dateRange = included ? { + startDate, + endDate, + selecting: false, + hoverDate: null, + anchorDate: null + } : undefined; + + return ( +
+ {days.map((date, i) => { + const dayOfWeek = date.getDay(); + const variations = getDateVariations(date, dateRange, weekendDays, dayOfWeek); + + const wrapperClasses = classNames( + styles.DateRange__DayWrapper, + { + [styles['DateRange__DayWrapper--rangeStart']]: variations.includes('rangeStart'), + [styles['DateRange__DayWrapper--rangeEnd']]: variations.includes('rangeEnd'), + [styles['DateRange__DayWrapper--selected']]: variations.includes('selected'), + } + ); + + return ( +
+ +
+ ); + })} +
+ ); +}; \ No newline at end of file diff --git a/src/examples/DateRangeView.tsx b/src/examples/DateRangeView.tsx new file mode 100644 index 0000000..2767129 --- /dev/null +++ b/src/examples/DateRangeView.tsx @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; +import { DateRange } from '../components/calendar/DateRange'; +import { Controls } from '../components/calendar/Controls'; +import { HeaderStyle, DaySize, MonthCutoffType } from '../types/calendar'; +import styles from './Examples.module.scss'; + +export const DateRangeView: React.FC = () => { + const [dayHeaderStyle, setDayHeaderStyle] = useState('tiny'); + const [size, setSize] = useState('l'); + const [fontProportion, setFontProportion] = useState(100); + const [included, setIncluded] = useState(true); + const [monthCutoff, setMonthCutoff] = useState(undefined); + + const fromDate = new Date(2025, 0, 15); // January 15, 2025 + const toDate = new Date(2025, 0, 22); // January 22, 2025 + + return ( +
+

Date Range View

+

+ Display a custom date range with optional selection highlighting. +

+ +
+ +
+
+ +
+
+
{``}
+
+
+ ); +}; \ No newline at end of file