@theengineerguy/chronos-picker 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Chronos Picker Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,386 @@
1
+ # 🕐 Chronos Picker
2
+
3
+ A modern, accessible, and fully-featured date & time picker for React with comprehensive timezone support.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@chronos/picker.svg)](https://www.npmjs.com/package/@chronos/picker)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## ✨ Features
9
+
10
+ - 🌍 **Full Timezone Support** - IANA timezone database with automatic DST handling
11
+ - ♿ **Accessible** - WCAG 2.1 compliant with full keyboard navigation
12
+ - 🎨 **Modern UI** - Beautiful design with smooth animations
13
+ - 📱 **Responsive** - Works seamlessly on desktop and mobile
14
+ - 🌙 **Dark Mode** - Automatic dark mode support
15
+ - 📦 **Lightweight** - Minimal dependencies (only Luxon for date handling)
16
+ - 🎯 **Type-Safe** - Full TypeScript support
17
+ - ⚡ **Performance** - Optimized rendering with React best practices
18
+
19
+ ## 📦 Installation
20
+
21
+ ```bash
22
+ npm install @chronos/picker luxon
23
+ ```
24
+
25
+ Or with yarn:
26
+
27
+ ```bash
28
+ yarn add @chronos/picker luxon
29
+ ```
30
+
31
+ ## 🚀 Quick Start
32
+
33
+ ```tsx
34
+ import React, { useState } from 'react';
35
+ import { DateTimePicker, DateTimeValue } from '@chronos/picker';
36
+
37
+ function App() {
38
+ const [value, setValue] = useState<DateTimeValue | null>(null);
39
+
40
+ const handleChange = (newValue: DateTimeValue) => {
41
+ setValue(newValue);
42
+ console.log('ISO:', newValue.iso);
43
+ console.log('Formatted:', newValue.formatted);
44
+ console.log('Timestamp:', newValue.timestamp);
45
+ };
46
+
47
+ return (
48
+ <DateTimePicker
49
+ value={value?.dateTime}
50
+ onChange={handleChange}
51
+ timezone="Asia/Kolkata"
52
+ placeholder="Select date and time"
53
+ />
54
+ );
55
+ }
56
+ ```
57
+
58
+ ## 📖 API Reference
59
+
60
+ ### DateTimePicker Props
61
+
62
+ | Prop | Type | Default | Description |
63
+ |------|------|---------|-------------|
64
+ | `value` | `Date \| string \| DateTime` | `undefined` | Current selected value |
65
+ | `onChange` | `(value: DateTimeValue) => void` | `undefined` | Callback when value changes |
66
+ | `timezone` | `string` | `"Asia/Kolkata"` | IANA timezone identifier |
67
+ | `dateFormat` | `string` | `"DD"` | Date format (Luxon tokens) |
68
+ | `timeFormat` | `string` | `"HH:mm"` | Time format (Luxon tokens) |
69
+ | `minDate` | `Date \| string` | `undefined` | Minimum selectable date |
70
+ | `maxDate` | `Date \| string` | `undefined` | Maximum selectable date |
71
+ | `placeholder` | `string` | `"Select date and time"` | Input placeholder text |
72
+ | `disabled` | `boolean` | `false` | Disable the picker |
73
+ | `showTime` | `boolean` | `true` | Show time picker |
74
+ | `use24Hour` | `boolean` | `true` | Use 24-hour format |
75
+ | `className` | `string` | `""` | Custom CSS class |
76
+ | `ariaLabel` | `string` | `"Date and time picker"` | ARIA label for accessibility |
77
+ | `showTimezoneSelector` | `boolean` | `false` | Show timezone selector |
78
+
79
+ ### DateTimeValue Type
80
+
81
+ ```typescript
82
+ interface DateTimeValue {
83
+ iso: string; // ISO 8601 string
84
+ formatted: string; // Formatted display string
85
+ timestamp: number; // Unix timestamp (ms)
86
+ dateTime: DateTime; // Luxon DateTime object
87
+ }
88
+ ```
89
+
90
+ ## 🎯 Usage Examples
91
+
92
+ ### Basic Usage with Default Timezone (IST)
93
+
94
+ ```tsx
95
+ import { DateTimePicker } from '@chronos/picker';
96
+
97
+ function BasicExample() {
98
+ return (
99
+ <DateTimePicker
100
+ onChange={(value) => console.log(value.iso)}
101
+ placeholder="Pick a date and time"
102
+ />
103
+ );
104
+ }
105
+ ```
106
+
107
+ ### With Custom Timezone
108
+
109
+ ```tsx
110
+ <DateTimePicker
111
+ timezone="America/New_York"
112
+ onChange={(value) => {
113
+ console.log('Selected time in New York:', value.formatted);
114
+ }}
115
+ />
116
+ ```
117
+
118
+ ### With Timezone Selector
119
+
120
+ ```tsx
121
+ <DateTimePicker
122
+ showTimezoneSelector
123
+ timezone="UTC"
124
+ onChange={(value) => {
125
+ console.log('Timezone:', value.dateTime.zoneName);
126
+ console.log('Offset:', value.dateTime.offset);
127
+ }}
128
+ />
129
+ ```
130
+
131
+ ### Date Only (No Time)
132
+
133
+ ```tsx
134
+ <DateTimePicker
135
+ showTime={false}
136
+ dateFormat="MMMM d, yyyy"
137
+ onChange={(value) => console.log(value.formatted)}
138
+ />
139
+ ```
140
+
141
+ ### 12-Hour Time Format
142
+
143
+ ```tsx
144
+ <DateTimePicker
145
+ use24Hour={false}
146
+ timeFormat="hh:mm a"
147
+ onChange={(value) => console.log(value.formatted)}
148
+ />
149
+ ```
150
+
151
+ ### With Date Range Restrictions
152
+
153
+ ```tsx
154
+ <DateTimePicker
155
+ minDate="2024-01-01"
156
+ maxDate="2024-12-31"
157
+ onChange={(value) => console.log('Selected:', value.iso)}
158
+ />
159
+ ```
160
+
161
+ ### Controlled Component
162
+
163
+ ```tsx
164
+ function ControlledExample() {
165
+ const [selectedDate, setSelectedDate] = useState<DateTime | null>(null);
166
+
167
+ return (
168
+ <div>
169
+ <DateTimePicker
170
+ value={selectedDate}
171
+ onChange={(value) => setSelectedDate(value.dateTime)}
172
+ />
173
+
174
+ <button onClick={() => setSelectedDate(DateTime.now())}>
175
+ Set to Now
176
+ </button>
177
+
178
+ <button onClick={() => setSelectedDate(null)}>
179
+ Clear
180
+ </button>
181
+ </div>
182
+ );
183
+ }
184
+ ```
185
+
186
+ ### Custom Format and Styling
187
+
188
+ ```tsx
189
+ <DateTimePicker
190
+ dateFormat="dd/MM/yyyy"
191
+ timeFormat="HH:mm:ss"
192
+ className="my-custom-picker"
193
+ ariaLabel="Event date and time"
194
+ onChange={(value) => console.log(value)}
195
+ />
196
+ ```
197
+
198
+ ### Multiple Timezones
199
+
200
+ ```tsx
201
+ function MultiTimezoneExample() {
202
+ const [indiaTime, setIndiaTime] = useState<DateTimeValue | null>(null);
203
+ const [nyTime, setNYTime] = useState<DateTimeValue | null>(null);
204
+
205
+ const handleIndiaChange = (value: DateTimeValue) => {
206
+ setIndiaTime(value);
207
+ // Convert to New York time
208
+ const converted = value.dateTime.setZone('America/New_York');
209
+ setNYTime({
210
+ ...value,
211
+ dateTime: converted,
212
+ formatted: converted.toFormat('DD HH:mm'),
213
+ iso: converted.toISO() || '',
214
+ });
215
+ };
216
+
217
+ return (
218
+ <div>
219
+ <div>
220
+ <label>India Time (IST)</label>
221
+ <DateTimePicker
222
+ timezone="Asia/Kolkata"
223
+ value={indiaTime?.dateTime}
224
+ onChange={handleIndiaChange}
225
+ />
226
+ </div>
227
+
228
+ <div>
229
+ <label>New York Time (EST/EDT)</label>
230
+ <DateTimePicker
231
+ timezone="America/New_York"
232
+ value={nyTime?.dateTime}
233
+ disabled
234
+ />
235
+ </div>
236
+ </div>
237
+ );
238
+ }
239
+ ```
240
+
241
+ ## 🌍 Supported Timezones
242
+
243
+ The component supports all IANA timezone identifiers. Common timezones are provided for quick selection:
244
+
245
+ - Asia/Kolkata (India - IST)
246
+ - America/New_York (Eastern Time)
247
+ - America/Chicago (Central Time)
248
+ - America/Denver (Mountain Time)
249
+ - America/Los_Angeles (Pacific Time)
250
+ - Europe/London (GMT/BST)
251
+ - Europe/Paris (CET)
252
+ - Asia/Dubai (GST)
253
+ - Asia/Singapore (SGT)
254
+ - Asia/Tokyo (JST)
255
+ - Australia/Sydney (AEDT)
256
+ - UTC
257
+
258
+ ## ♿ Accessibility
259
+
260
+ Chronos Picker is built with accessibility in mind:
261
+
262
+ - **Keyboard Navigation**: Full keyboard support (Tab, Enter, Space, Arrow keys, Escape)
263
+ - **ARIA Labels**: Comprehensive ARIA attributes for screen readers
264
+ - **Focus Management**: Proper focus indicators and logical tab order
265
+ - **Screen Reader Support**: Announced date selections and state changes
266
+ - **WCAG 2.1 Compliant**: Meets AA level accessibility standards
267
+
268
+ ### Keyboard Shortcuts
269
+
270
+ - `Tab` / `Shift+Tab` - Navigate between elements
271
+ - `Enter` / `Space` - Select date/time or toggle dropdown
272
+ - `Arrow Keys` - Navigate calendar grid
273
+ - `Escape` - Close picker
274
+
275
+ ## 🎨 Styling
276
+
277
+ The component comes with beautiful default styles, but you can customize it:
278
+
279
+ ### Custom CSS
280
+
281
+ ```css
282
+ /* Override default styles */
283
+ .my-custom-picker .chronos-input {
284
+ border-color: #your-color;
285
+ border-radius: 12px;
286
+ }
287
+
288
+ .my-custom-picker .chronos-day.selected {
289
+ background-color: #your-brand-color;
290
+ }
291
+ ```
292
+
293
+ ### Tailwind CSS
294
+
295
+ ```tsx
296
+ <DateTimePicker
297
+ className="w-full max-w-md"
298
+ onChange={handleChange}
299
+ />
300
+ ```
301
+
302
+ ## 🔧 Advanced Usage
303
+
304
+ ### Working with Luxon DateTime
305
+
306
+ ```tsx
307
+ import { DateTime } from 'luxon';
308
+
309
+ function AdvancedExample() {
310
+ const handleChange = (value: DateTimeValue) => {
311
+ const dt = value.dateTime;
312
+
313
+ // Access Luxon DateTime methods
314
+ console.log('Day of week:', dt.weekdayLong);
315
+ console.log('Week number:', dt.weekNumber);
316
+ console.log('Is DST:', dt.isInDST);
317
+
318
+ // Format in different ways
319
+ console.log('ISO:', dt.toISO());
320
+ console.log('SQL:', dt.toSQL());
321
+ console.log('Relative:', dt.toRelative());
322
+
323
+ // Convert to other timezones
324
+ const tokyo = dt.setZone('Asia/Tokyo');
325
+ console.log('Tokyo time:', tokyo.toFormat('HH:mm'));
326
+ };
327
+
328
+ return <DateTimePicker onChange={handleChange} />;
329
+ }
330
+ ```
331
+
332
+ ### Timezone Conversion Helper
333
+
334
+ ```tsx
335
+ import { convertToTimezone } from '@chronos/picker';
336
+
337
+ // Convert a date to specific timezone
338
+ const indiaTime = new Date();
339
+ const tokyoTime = convertToTimezone(indiaTime, 'Asia/Tokyo');
340
+ console.log(tokyoTime.toISO());
341
+ ```
342
+
343
+ ## 🐛 Troubleshooting
344
+
345
+ ### Date not updating
346
+
347
+ Make sure you're using a controlled component pattern:
348
+
349
+ ```tsx
350
+ const [date, setDate] = useState<DateTime | null>(null);
351
+
352
+ <DateTimePicker
353
+ value={date}
354
+ onChange={(value) => setDate(value.dateTime)}
355
+ />
356
+ ```
357
+
358
+ ### Timezone not changing
359
+
360
+ Ensure you're using valid IANA timezone identifiers. Check the [IANA timezone database](https://www.iana.org/time-zones).
361
+
362
+ ### Styling issues
363
+
364
+ Import the CSS file in your component or main app file:
365
+
366
+ ```tsx
367
+ import '@chronos/picker/dist/style.css';
368
+ ```
369
+
370
+ ## 📄 License
371
+
372
+ MIT © [Your Name]
373
+
374
+ ## 🤝 Contributing
375
+
376
+ Contributions are welcome! Please feel free to submit a Pull Request.
377
+
378
+ ## 🙏 Acknowledgments
379
+
380
+ - Built with [React](https://reactjs.org/)
381
+ - Date handling by [Luxon](https://moment.github.io/luxon/)
382
+ - Inspired by modern design systems
383
+
384
+ ---
385
+
386
+ Made with ❤️ by developers, for developers
@@ -0,0 +1,15 @@
1
+ import { default as React } from 'react';
2
+ import { DateTime } from 'luxon';
3
+
4
+ interface CalendarProps {
5
+ viewDate: DateTime;
6
+ selectedDate: DateTime | null;
7
+ onDateSelect: (date: DateTime) => void;
8
+ onViewDateChange: (date: DateTime) => void;
9
+ timezone: string;
10
+ minDate?: DateTime;
11
+ maxDate?: DateTime;
12
+ }
13
+ export declare const Calendar: React.FC<CalendarProps>;
14
+ export {};
15
+ //# sourceMappingURL=Calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../src/components/Calendar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,UAAU,aAAa;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,gBAAgB,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA8I5C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+ import { DateTimePickerProps } from '../types';
3
+
4
+ export declare const DateTimePicker: React.FC<DateTimePickerProps>;
5
+ //# sourceMappingURL=DateTimePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../../src/components/DateTimePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAE,mBAAmB,EAAiB,MAAM,UAAU,CAAC;AAK9D,OAAO,8BAA8B,CAAC;AAEtC,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAoOxD,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { default as React } from 'react';
2
+ import { DateTime } from 'luxon';
3
+
4
+ interface TimePickerProps {
5
+ value: DateTime | null;
6
+ onChange: (hour: number, minute: number) => void;
7
+ use24Hour: boolean;
8
+ timezone: string;
9
+ }
10
+ export declare const TimePicker: React.FC<TimePickerProps>;
11
+ export {};
12
+ //# sourceMappingURL=TimePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimePicker.d.ts","sourceRoot":"","sources":["../../src/components/TimePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,UAAU,eAAe;IACvB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAqIhD,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface TimezoneSelectorProps {
4
+ value: string;
5
+ onChange: (timezone: string) => void;
6
+ }
7
+ export declare const TimezoneSelector: React.FC<TimezoneSelectorProps>;
8
+ export {};
9
+ //# sourceMappingURL=TimezoneSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimezoneSelector.d.ts","sourceRoot":"","sources":["../../src/components/TimezoneSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAgF5D,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { DateTimePicker } from './components/DateTimePicker';
2
+ export type { DateTimePickerProps, DateTimeValue } from './types';
3
+ export { DEFAULT_TIMEZONE, COMMON_TIMEZONES, convertToTimezone, nowInTimezone } from './utils/timezone';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}