react-modular-datepicker 0.0.2 → 0.0.3-canary.1
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 +195 -4
- package/dist/index.css +460 -128
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/docs/images/availability.png +0 -0
- package/docs/images/basic.png +0 -0
- package/docs/images/custom-header-footer.png +0 -0
- package/docs/images/custom-styling.png +0 -0
- package/docs/images/events.png +0 -0
- package/docs/images/form-integration.png +0 -0
- package/docs/images/headless.png +0 -0
- package/docs/images/hero-calendar.png +0 -0
- package/docs/images/localization.png +0 -0
- package/docs/images/min-max-disabled.png +0 -0
- package/docs/images/multiple.png +0 -0
- package/docs/images/range.png +0 -0
- package/docs/images/styling.png +0 -0
- package/docs/images/yearly.png +0 -0
- package/package.json +35 -3
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
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
4
|
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="./docs/images/hero-calendar.png" alt="react-modular-datepicker preview" width="320" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
5
9
|
## Strengths
|
|
6
10
|
|
|
7
11
|
- 🏗️ **Headless & Modular**: Use the `useDates` hook for complete control over your UI, or the `Calendar` component for a beautiful, ready-to-use setup.
|
|
@@ -103,11 +107,15 @@ function BasicExample() {
|
|
|
103
107
|
}
|
|
104
108
|
```
|
|
105
109
|
|
|
110
|
+
<br />
|
|
111
|
+
|
|
112
|
+
<img src="./docs/images/basic.png" alt="Basic Selection" width="500" />
|
|
113
|
+
|
|
106
114
|
</details>
|
|
107
115
|
|
|
108
116
|
<details>
|
|
109
117
|
<summary><b>Range Selection</b></summary>
|
|
110
|
-
Select a start and end date with a
|
|
118
|
+
Select a start and end date with a hover preview.
|
|
111
119
|
|
|
112
120
|
```tsx
|
|
113
121
|
<Calendar
|
|
@@ -117,6 +125,10 @@ Select a start and end date with a beautiful hover preview.
|
|
|
117
125
|
/>
|
|
118
126
|
```
|
|
119
127
|
|
|
128
|
+
<br />
|
|
129
|
+
|
|
130
|
+
<img src="./docs/images/range.png" alt="Range Selection" width="500" />
|
|
131
|
+
|
|
120
132
|
</details>
|
|
121
133
|
|
|
122
134
|
<details>
|
|
@@ -130,6 +142,10 @@ Select as many dates as you want.
|
|
|
130
142
|
/>
|
|
131
143
|
```
|
|
132
144
|
|
|
145
|
+
<br />
|
|
146
|
+
|
|
147
|
+
<img src="./docs/images/multiple.png" alt="Multiple Selection" width="500" />
|
|
148
|
+
|
|
133
149
|
</details>
|
|
134
150
|
|
|
135
151
|
<details>
|
|
@@ -152,6 +168,10 @@ return (
|
|
|
152
168
|
);
|
|
153
169
|
```
|
|
154
170
|
|
|
171
|
+
<br />
|
|
172
|
+
|
|
173
|
+
<img src="./docs/images/headless.png" alt="Headless Usage" width="500" />
|
|
174
|
+
|
|
155
175
|
</details>
|
|
156
176
|
|
|
157
177
|
<details>
|
|
@@ -161,15 +181,186 @@ Easily customize the look and feel using the `classNames` prop.
|
|
|
161
181
|
```tsx
|
|
162
182
|
<Calendar
|
|
163
183
|
classNames={{
|
|
164
|
-
root: 'bg-
|
|
184
|
+
root: 'bg-stone-50 p-6 rounded-2xl border border-stone-200 shadow-lg text-stone-800',
|
|
185
|
+
monthYearLabel: 'font-serif text-stone-900 text-lg font-bold',
|
|
165
186
|
day: {
|
|
166
|
-
|
|
167
|
-
|
|
187
|
+
unselected: 'bg-white border border-stone-200 hover:bg-amber-100/50 text-stone-800',
|
|
188
|
+
selected: 'bg-amber-800 text-amber-50 font-bold',
|
|
168
189
|
}
|
|
169
190
|
}}
|
|
170
191
|
/>
|
|
171
192
|
```
|
|
172
193
|
|
|
194
|
+
<br />
|
|
195
|
+
|
|
196
|
+
<img src="./docs/images/custom-styling.png" alt="Custom Styling" width="500" />
|
|
197
|
+
|
|
198
|
+
</details>
|
|
199
|
+
|
|
200
|
+
<details>
|
|
201
|
+
<summary><b>Localization & i18n</b></summary>
|
|
202
|
+
Easily customize language, month/weekday labels, and the first day of week.
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
<Calendar
|
|
206
|
+
firstDayOfWeek={1} // Start week on Monday
|
|
207
|
+
translations={{
|
|
208
|
+
months: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
|
|
209
|
+
weekdays: ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'],
|
|
210
|
+
}}
|
|
211
|
+
/>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
<br />
|
|
215
|
+
|
|
216
|
+
<img src="./docs/images/localization.png" alt="Localization & i18n" width="500" />
|
|
217
|
+
|
|
218
|
+
</details>
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary><b>Form Integration</b></summary>
|
|
222
|
+
Integrate the calendar into a form or popup.
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
const [date, setDate] = useState<Date | null>(null);
|
|
226
|
+
|
|
227
|
+
<div className="relative group">
|
|
228
|
+
<input
|
|
229
|
+
type="text"
|
|
230
|
+
readOnly
|
|
231
|
+
value={date ? date.toLocaleDateString() : ''}
|
|
232
|
+
placeholder="Pick a date"
|
|
233
|
+
/>
|
|
234
|
+
<div className="absolute top-full left-0 mt-2 z-50 invisible group-focus-within:visible">
|
|
235
|
+
<Calendar
|
|
236
|
+
selected={date}
|
|
237
|
+
onChange={(d) => setDate(d as Date)}
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
<br />
|
|
244
|
+
|
|
245
|
+
<img src="./docs/images/form-integration.png" alt="Form Integration" width="500" />
|
|
246
|
+
|
|
247
|
+
</details>
|
|
248
|
+
|
|
249
|
+
<details>
|
|
250
|
+
<summary><b>Custom Header & Footer</b></summary>
|
|
251
|
+
Customize header, footer, and day tooltips.
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
<Calendar
|
|
255
|
+
selected={selected}
|
|
256
|
+
onChange={(val) => setSelected(val as Date)}
|
|
257
|
+
monthsToDisplay={2}
|
|
258
|
+
header={<div className="p-2 bg-blue-100 text-blue-800 font-bold text-center rounded-t-lg">My Header</div>}
|
|
259
|
+
footer={<div className="p-2 bg-gray-100 text-gray-600 text-sm text-center rounded-b-lg border-t">My Custom Footer</div>}
|
|
260
|
+
renderDayTooltip={(dateObj) => (
|
|
261
|
+
dateObj.date.getDate() === 15 ? 'Middle of the month!' : null
|
|
262
|
+
)}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
<br />
|
|
267
|
+
|
|
268
|
+
<img src="./docs/images/custom-header-footer.png" alt="Custom Header & Footer" width="500" />
|
|
269
|
+
|
|
270
|
+
</details>
|
|
271
|
+
|
|
272
|
+
<details>
|
|
273
|
+
<summary><b>Min, Max & Disabled Dates</b></summary>
|
|
274
|
+
Restrict date selection with min/max bounds or specific disabled dates.
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
<Calendar
|
|
278
|
+
selected={selected}
|
|
279
|
+
onChange={(val) => setSelected(val as Date)}
|
|
280
|
+
minDate={minDate}
|
|
281
|
+
maxDate={maxDate}
|
|
282
|
+
disabledDates={[disabledDate1, disabledDate2]}
|
|
283
|
+
/>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
<br />
|
|
287
|
+
|
|
288
|
+
<img src="./docs/images/min-max-disabled.png" alt="Min, Max & Disabled Dates" width="500" />
|
|
289
|
+
|
|
290
|
+
</details>
|
|
291
|
+
|
|
292
|
+
<details>
|
|
293
|
+
<summary><b>Yearly View</b></summary>
|
|
294
|
+
Display an entire year at once by customizing the grid and `monthsToDisplay`.
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
<Calendar
|
|
298
|
+
selected={selected}
|
|
299
|
+
onChange={(val) => setSelected(val as Date)}
|
|
300
|
+
monthsToDisplay={12}
|
|
301
|
+
classNames={{
|
|
302
|
+
calendarsContainer: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"
|
|
303
|
+
}}
|
|
304
|
+
/>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
<br />
|
|
308
|
+
|
|
309
|
+
<img src="./docs/images/yearly.png" alt="Yearly View" width="500" />
|
|
310
|
+
|
|
311
|
+
</details>
|
|
312
|
+
|
|
313
|
+
<details>
|
|
314
|
+
<summary><b>Availability & Async Data</b></summary>
|
|
315
|
+
Fetch and display availability dynamically when the month changes.
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
<Calendar
|
|
319
|
+
selected={selected}
|
|
320
|
+
onChange={(val) => setSelected(val as Date)}
|
|
321
|
+
onMonthChange={(date) => fetchAvailabilities(date)}
|
|
322
|
+
modifiers={{
|
|
323
|
+
available: (date) => availabilities[date.toDateString()] === true,
|
|
324
|
+
unavailable: (date) => availabilities[date.toDateString()] === false,
|
|
325
|
+
}}
|
|
326
|
+
disabledDates={
|
|
327
|
+
Object.keys(availabilities)
|
|
328
|
+
.filter(key => !availabilities[key])
|
|
329
|
+
.map(key => new Date(key))
|
|
330
|
+
}
|
|
331
|
+
classNames={{
|
|
332
|
+
day: {
|
|
333
|
+
available: "bg-green-100 text-green-800 hover:bg-green-200",
|
|
334
|
+
unavailable: "bg-red-50 text-red-300 line-through cursor-not-allowed",
|
|
335
|
+
}
|
|
336
|
+
}}
|
|
337
|
+
/>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
<br />
|
|
341
|
+
|
|
342
|
+
<img src="./docs/images/availability.png" alt="Availability Demo" width="500" />
|
|
343
|
+
|
|
344
|
+
</details>
|
|
345
|
+
|
|
346
|
+
<details>
|
|
347
|
+
<summary><b>Full-Featured / Events Calendar (Google Calendar style)</b></summary>
|
|
348
|
+
Build a full-page events calendar using the `useDates` hook.
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
const { calendars, getBackProps, getForwardProps, getDateProps } = useDates({
|
|
352
|
+
showOutsideDays: true,
|
|
353
|
+
selected: selectedDate,
|
|
354
|
+
onChange: (d) => setSelectedDate(d as Date),
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// Render custom full-grid layout with event badges...
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
<br />
|
|
361
|
+
|
|
362
|
+
<img src="./docs/images/events.png" alt="Events Calendar" width="500" />
|
|
363
|
+
|
|
173
364
|
</details>
|
|
174
365
|
|
|
175
366
|
---
|