react-modular-datepicker 0.0.2-canary.4 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,2 +1,218 @@
1
1
  # react-modular-datepicker
2
- A headless datepicker
2
+
3
+ A modular, lightweight, and type-safe React datepicker library. Whether you need a fully-featured calendar component or a headless hook to build your own UI, `react-modular-datepicker` has you covered.
4
+
5
+ ## Strengths
6
+
7
+ - đŸ—ī¸ **Headless & Modular**: Use the `useDates` hook for complete control over your UI, or the `Calendar` component for a beautiful, ready-to-use setup.
8
+ - đŸĒļ **Lightweight**: Small footprint with a pluggable adapter system (defaults to Day.js).
9
+ - đŸ›Ąī¸ **Type-safe**: Written in TypeScript for a great developer experience.
10
+ - 🎨 **Fully Customizable**: Style everything via Tailwind CSS or custom class names.
11
+ - 🌍 **Localized**: Easy internationalization support with `dayjs` or custom adapters.
12
+ - ⚡ **Feature-rich**: Single, multiple, and range selection modes, min/max dates, disabled dates, and more.
13
+
14
+ ---
15
+
16
+ ## API Reference
17
+
18
+ ### Imports
19
+
20
+ ```tsx
21
+ import {
22
+ Calendar,
23
+ useDates,
24
+ Dates,
25
+ Day,
26
+ DayjsAdapter,
27
+ defaultAdapter
28
+ } from 'react-modular-datepicker';
29
+ ```
30
+
31
+ ### `Calendar` Component
32
+
33
+ The primary component for a ready-to-use calendar.
34
+
35
+ | Prop | Type | Default | Description |
36
+ | :--- | :--- | :--- | :--- |
37
+ | `date` | `Date` | `new Date()` | The initial date/month to display. |
38
+ | `selected` | `Date \| Date[] \| Range` | `undefined` | The currently selected date(s). |
39
+ | `selectionMode` | `'single' \| 'range' \| 'multiple'` | `'single'` | The selection behavior. |
40
+ | `onChange` | `(selected: any) => void` | `undefined` | Callback triggered when the selection changes. |
41
+ | `minDate` | `Date` | `undefined` | The earliest selectable date. |
42
+ | `maxDate` | `Date` | `undefined` | The latest selectable date. |
43
+ | `disabledDates` | `Date[]` | `undefined` | An array of dates that should be disabled. |
44
+ | `monthsToDisplay` | `number` | `1` | Number of months to show simultaneously. |
45
+ | `firstDayOfWeek` | `number` | `0` | The first day of the week (0=Sun, 1=Mon, ...). |
46
+ | `showOutsideDays` | `boolean` | `false` | Whether to show days from the previous/next months. |
47
+ | `classNames` | `CalendarClassNames` | `undefined` | Custom classes for styling various parts of the UI. |
48
+ | `locale` | `string` | `undefined` | Locale for date formatting (e.g., 'fr', 'es'). |
49
+ | `translations` | `Partial<Translations>` | `undefined` | Custom translation strings for "Back" and "Forward". |
50
+ | `adapter` | `DateAdapter` | `defaultAdapter` | The date management adapter (e.g., DayjsAdapter). |
51
+
52
+ ### `useDates` Hook
53
+
54
+ The logic core of the library. It handles selection, navigation, and grid generation.
55
+
56
+ ```typescript
57
+ const {
58
+ calendars,
59
+ getDateProps,
60
+ getBackProps,
61
+ getForwardProps,
62
+ setOffset
63
+ } = useDates(props: UseDatesProps);
64
+ ```
65
+
66
+ **`UseDatesProps`** includes all props from `Calendar` (except `classNames`, `locale`, `translations`) plus:
67
+ - `onDateSelected`: `(dateObj: DateObj, event: any) => void`
68
+ - `onOffsetChanged`: `(newOffset: number) => void`
69
+ - `modifiers`: `Record<string, (date: Date) => boolean>`
70
+
71
+ ### Main Types
72
+
73
+ #### `DateObj`
74
+ Represents a single day in the calendar grid.
75
+ - `date`: `Date`
76
+ - `selected`: `boolean`
77
+ - `selectable`: `boolean`
78
+ - `today`: `boolean`
79
+ - `prevMonth`/`nextMonth`: `boolean` (if outside current month)
80
+ - `isRangeStart`/`isRangeEnd`/`isRangeBetween`/`isRangeHovering`: `boolean`
81
+ - `modifiers`: `string[]`
82
+
83
+ #### `Calendar`
84
+ Represents a month grid.
85
+ - `month`: `number` (0-11)
86
+ - `year`: `number`
87
+ - `weeks`: `(DateObj | null)[][]`
88
+
89
+ ---
90
+
91
+ ## Recipes
92
+
93
+ <details>
94
+ <summary><b>Basic Selection</b></summary>
95
+ A simple single-date selection calendar.
96
+
97
+ ```tsx
98
+ import { Calendar } from 'react-modular-datepicker';
99
+ import 'react-modular-datepicker/dist/index.css';
100
+
101
+ function BasicExample() {
102
+ return <Calendar onChange={(date) => console.log(date)} />;
103
+ }
104
+ ```
105
+
106
+ </details>
107
+
108
+ <details>
109
+ <summary><b>Range Selection</b></summary>
110
+ Select a start and end date with a beautiful hover preview.
111
+
112
+ ```tsx
113
+ <Calendar
114
+ selectionMode="range"
115
+ monthsToDisplay={2}
116
+ onChange={(range) => console.log(range)}
117
+ />
118
+ ```
119
+
120
+ </details>
121
+
122
+ <details>
123
+ <summary><b>Multiple Selection</b></summary>
124
+ Select as many dates as you want.
125
+
126
+ ```tsx
127
+ <Calendar
128
+ selectionMode="multiple"
129
+ onChange={(dates) => console.log(dates)}
130
+ />
131
+ ```
132
+
133
+ </details>
134
+
135
+ <details>
136
+ <summary><b>Headless Usage</b></summary>
137
+ Complete freedom over your UI using the `useDates` hook.
138
+
139
+ ```tsx
140
+ const { calendars, getDateProps } = useDates({ selectionMode: 'single' });
141
+
142
+ return (
143
+ <div className="grid grid-cols-7">
144
+ {calendars[0].weeks.flat().map((dateObj, i) => (
145
+ dateObj ? (
146
+ <button key={i} {...getDateProps({ dateObj })}>
147
+ {dateObj.date.getDate()}
148
+ </button>
149
+ ) : <div key={i} />
150
+ ))}
151
+ </div>
152
+ );
153
+ ```
154
+
155
+ </details>
156
+
157
+ <details>
158
+ <summary><b>Custom Styling</b></summary>
159
+ Easily customize the look and feel using the `classNames` prop.
160
+
161
+ ```tsx
162
+ <Calendar
163
+ classNames={{
164
+ root: 'bg-indigo-900 text-white',
165
+ day: {
166
+ selected: 'bg-pink-500 text-white',
167
+ today: 'border-pink-500 text-pink-500',
168
+ }
169
+ }}
170
+ />
171
+ ```
172
+
173
+ </details>
174
+
175
+ ---
176
+
177
+ ## Contributors
178
+
179
+ We welcome contributions! Here’s how you can get started:
180
+
181
+ ### Installation
182
+
183
+ 1. Clone the repository.
184
+ 2. Install dependencies:
185
+ ```bash
186
+ pnpm install
187
+ ```
188
+
189
+ ### Development
190
+
191
+ Start the development server with the example app:
192
+ ```bash
193
+ pnpm run dev
194
+ ```
195
+ This runs `vite` in watch mode for the library and starts the Next.js example app at `http://localhost:3000`.
196
+
197
+ ### Testing
198
+
199
+ Run end-to-end tests using Playwright:
200
+ ```bash
201
+ pnpm run test:e2e
202
+ ```
203
+
204
+ ### Documentation & Examples
205
+
206
+ - To update documentation, edit the `README.md`.
207
+ - To add or modify examples, check the `examples/` directory.
208
+
209
+ ### Building
210
+
211
+ Build the package for production:
212
+ ```bash
213
+ pnpm run build
214
+ ```
215
+
216
+ ---
217
+
218
+ License: MIT
@@ -0,0 +1,21 @@
1
+ import { Dayjs } from 'dayjs';
2
+ import { DateAdapter } from '../types';
3
+ export declare class DayjsAdapter implements DateAdapter<Dayjs> {
4
+ date(value?: any): Dayjs;
5
+ add(date: Dayjs, amount: number, unit: 'day' | 'month' | 'year'): Dayjs;
6
+ subtract(date: Dayjs, amount: number, unit: 'day' | 'month' | 'year'): Dayjs;
7
+ startOf(date: Dayjs, unit: 'day' | 'month' | 'year'): Dayjs;
8
+ endOf(date: Dayjs, unit: 'day' | 'month' | 'year'): Dayjs;
9
+ isBefore(date: Dayjs, comparison: Dayjs, unit?: 'day' | 'month' | 'year'): boolean;
10
+ isAfter(date: Dayjs, comparison: Dayjs, unit?: 'day' | 'month' | 'year'): boolean;
11
+ isSame(date: Dayjs, comparison: Dayjs, unit?: 'day' | 'month' | 'year'): boolean;
12
+ set(date: Dayjs, unit: 'day' | 'month' | 'year', value: number): Dayjs;
13
+ get(date: Dayjs, unit: 'day' | 'month' | 'year'): number;
14
+ format(date: Dayjs, formatStr: string, locale?: string): string;
15
+ getDaysInMonth(date: Dayjs): number;
16
+ toDate(date: Dayjs): Date;
17
+ diff(date: Dayjs, comparison: Dayjs, unit: 'month' | 'year'): number;
18
+ getMonths(locale?: string): string[];
19
+ getWeekdays(locale?: string): string[];
20
+ }
21
+ export declare const defaultAdapter: DayjsAdapter;
@@ -0,0 +1,67 @@
1
+ export interface DayClassNames {
2
+ day?: string;
3
+ selected?: string;
4
+ unselected?: string;
5
+ disabled?: string;
6
+ rangeStart?: string;
7
+ rangeEnd?: string;
8
+ rangeBetween?: string;
9
+ rangeHovering?: string;
10
+ [key: string]: string | undefined;
11
+ }
12
+ export declare const defaultClassNames: {
13
+ root: string;
14
+ header: string;
15
+ calendarsContainer: string;
16
+ calendarContainer: string;
17
+ weekdayGrid: string;
18
+ weekday: string;
19
+ daysGrid: string;
20
+ footer: string;
21
+ navButton: string;
22
+ monthYearContainer: string;
23
+ monthYearLabel: string;
24
+ monthYearButton: string;
25
+ day: {
26
+ day: string;
27
+ selected: string;
28
+ unselected: string;
29
+ disabled: string;
30
+ rangeStart: string;
31
+ rangeEnd: string;
32
+ rangeBetween: string;
33
+ rangeHovering: string;
34
+ };
35
+ monthsGrid: string;
36
+ monthButton: string;
37
+ monthButtonSelected: string;
38
+ monthButtonUnselected: string;
39
+ yearsGrid: string;
40
+ yearButton: string;
41
+ yearButtonSelected: string;
42
+ yearButtonUnselected: string;
43
+ };
44
+ export interface CalendarClassNames {
45
+ root?: string;
46
+ header?: string;
47
+ calendarsContainer?: string;
48
+ calendarContainer?: string;
49
+ weekdayGrid?: string;
50
+ weekday?: string;
51
+ daysGrid?: string;
52
+ footer?: string;
53
+ navButton?: string;
54
+ monthYearContainer?: string;
55
+ monthYearLabel?: string;
56
+ monthYearButton?: string;
57
+ day?: DayClassNames;
58
+ monthsGrid?: string;
59
+ monthButton?: string;
60
+ monthButtonSelected?: string;
61
+ monthButtonUnselected?: string;
62
+ yearsGrid?: string;
63
+ yearButton?: string;
64
+ yearButtonSelected?: string;
65
+ yearButtonUnselected?: string;
66
+ }
67
+ export declare const mergeClassNames: (custom?: CalendarClassNames) => Required<CalendarClassNames>;
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ import { UseDatesProps } from '../useDates';
3
+ import { Translations } from '../i18n';
4
+ import { DateObj, CalendarClassNames } from '../types';
5
+ interface CalendarProps extends UseDatesProps {
6
+ classNames?: CalendarClassNames;
7
+ locale?: string;
8
+ translations?: Partial<Translations>;
9
+ header?: React.ReactNode | ((props: any) => React.ReactNode);
10
+ footer?: React.ReactNode;
11
+ renderDayTooltip?: (dateObj: DateObj) => React.ReactNode;
12
+ }
13
+ export declare const Calendar: React.FC<CalendarProps>;
14
+ export {};
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+ import { Calendar, CalendarClassNames } from '../types';
3
+ export interface HeaderProps {
4
+ calendars: Calendar[];
5
+ getBackProps: (args: any) => any;
6
+ getForwardProps: (args: any) => any;
7
+ setView: (view: 'days' | 'months' | 'years') => void;
8
+ monthNames: string[];
9
+ t: {
10
+ back: string;
11
+ forward: string;
12
+ };
13
+ classNames: Required<CalendarClassNames>;
14
+ slideDirection?: 'left' | 'right' | null;
15
+ currentView?: 'days' | 'months' | 'years';
16
+ }
17
+ export declare const ChevronLeftIcon: () => React.JSX.Element;
18
+ export declare const ChevronRightIcon: () => React.JSX.Element;
19
+ export declare const CalendarHeader: React.FC<HeaderProps>;
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { CalendarClassNames, DateObj } from '../types';
3
+ interface DayProps {
4
+ dateObj: DateObj | null;
5
+ getDateProps: (args: {
6
+ dateObj: DateObj;
7
+ [key: string]: any;
8
+ }) => any;
9
+ tooltip?: React.ReactNode;
10
+ classNames: Required<CalendarClassNames>;
11
+ }
12
+ export declare const Day: React.FC<DayProps>;
13
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { CalendarClassNames } from '../types';
3
+ interface MonthSelectionProps {
4
+ year: number;
5
+ month: number;
6
+ monthNames: string[];
7
+ minDate?: Date | null;
8
+ maxDate?: Date | null;
9
+ onMonthSelect: (month: number) => void;
10
+ classNames: Required<CalendarClassNames>;
11
+ }
12
+ export declare const MonthSelection: React.FC<MonthSelectionProps>;
13
+ export {};
@@ -0,0 +1,12 @@
1
+ import { default as React } from 'react';
2
+ import { CalendarClassNames, DateAdapter } from '../types';
3
+ interface YearSelectionProps {
4
+ year: number;
5
+ minDate?: Date | null;
6
+ maxDate?: Date | null;
7
+ adapter: DateAdapter;
8
+ onYearSelect: (year: number) => void;
9
+ classNames: Required<CalendarClassNames>;
10
+ }
11
+ export declare const YearSelection: React.FC<YearSelectionProps>;
12
+ export {};
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { DateAdapter } from './types';
2
+ export interface Translations {
3
+ months: string[];
4
+ weekdays: string[];
5
+ back: string;
6
+ forward: string;
7
+ }
8
+ export declare function getDefaults(adapter?: DateAdapter, locale?: string): Translations;
9
+ export declare function getTranslations(adapter?: DateAdapter, locale?: string, custom?: Partial<Translations>): Translations;