@theengineerguy/chronos-picker 1.0.3 → 1.0.4
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 +21 -21
- package/README.md +386 -386
- package/dist/style.css +1 -1
- package/package.json +61 -61
package/LICENSE
CHANGED
|
@@ -1,21 +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.
|
|
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
CHANGED
|
@@ -1,386 +1,386 @@
|
|
|
1
|
-
# 🕐 Chronos Picker
|
|
2
|
-
|
|
3
|
-
A modern, accessible, and fully-featured date & time picker for React with comprehensive timezone support.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@chronos/picker)
|
|
6
|
-
[](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
|
|
1
|
+
# 🕐 Chronos Picker
|
|
2
|
+
|
|
3
|
+
A modern, accessible, and fully-featured date & time picker for React with comprehensive timezone support.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@chronos/picker)
|
|
6
|
+
[](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 Debmalya, for developers
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.chronos-picker{position:relative;display:inline-block;width:100%;max-width:320px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;color:#1a1a1a}.chronos-picker[data-disabled=true]{opacity:.6;cursor:not-allowed}.chronos-input-wrapper{position:relative;display:flex;align-items:center;cursor:pointer}.chronos-input{width:100%;padding:10px 40px 10px 14px;border:1.5px solid #d1d5db;border-radius:8px;font-size:14px;color:#1a1a1a;background-color:#fff;transition:all .2s ease;cursor:pointer;outline:none}.chronos-input:hover:not(:disabled){border-color:#9ca3af}.chronos-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-input:disabled{background-color:#f3f4f6;cursor:not-allowed}.chronos-input::placeholder{color:#9ca3af}.chronos-calendar-icon{position:absolute;right:12px;width:20px;height:20px;color:#6b7280;pointer-events:none;transition:color .2s ease}.chronos-input:hover:not(:disabled)~.chronos-calendar-icon,.chronos-input:focus~.chronos-calendar-icon{color:#3b82f6}.chronos-dropdown{position:absolute;top:calc(100% + 8px);left:0;z-index:9999;min-width:320px;background:#fff;border:1px solid #e5e7eb;border-radius:14px;box-shadow:0 4px 6px -1px #00000014,0 10px 30px -4px #0000001f;overflow:hidden;animation:chronos-dropdown-appear .2s ease}.chronos-dropdown-content{display:flex;flex-direction:column}.chronos-dropdown[data-orientation=portrait] .chronos-dropdown-content{flex-direction:column}.chronos-dropdown[data-orientation=landscape]{min-width:auto}.chronos-dropdown[data-orientation=landscape] .chronos-dropdown-content{flex-direction:row}.chronos-dropdown[data-orientation=landscape] .chronos-calendar{border-right:1px solid #e5e7eb;border-bottom:none}.chronos-dropdown[data-orientation=landscape] .chronos-sidebar{display:flex;flex-direction:column;min-width:240px}.chronos-dropdown[data-orientation=landscape] .chronos-time-picker{border-top:none;border-bottom:1px solid #e5e7eb}.chronos-dropdown[data-orientation=landscape] .chronos-time-picker:last-child{border-bottom:none}.chronos-dropdown[data-orientation=landscape] .chronos-timezone-selector{border-top:none}@keyframes chronos-dropdown-appear{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.chronos-range-summary{padding:16px 16px 0;margin-bottom:8px}.chronos-range-nights{font-size:1.5rem;font-weight:700;color:#1a1a1a;letter-spacing:-.025em;line-height:1.2}.chronos-range-dates{font-size:.875rem;color:#6b7280;margin-top:4px}.chronos-calendar{padding:16px}.chronos-calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;gap:8px}.chronos-nav-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:#4b5563;font-size:20px;font-weight:600;cursor:pointer;transition:all .15s ease}.chronos-nav-button:hover{background:#f3f4f6;color:#1a1a1a}.chronos-nav-button:active{transform:scale(.95)}.chronos-month-year-selectors{display:flex;gap:8px;flex:1;justify-content:center}.chronos-month-select,.chronos-year-select{padding:6px 10px;border:1px solid #d1d5db;border-radius:6px;font-size:14px;font-weight:500;color:#1a1a1a;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none}.chronos-month-select:hover,.chronos-year-select:hover{border-color:#9ca3af}.chronos-month-select:focus,.chronos-year-select:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-calendar-grid{display:flex;flex-direction:column;gap:4px}.chronos-weekday-row,.chronos-week-row{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.chronos-weekday{display:flex;align-items:center;justify-content:center;height:32px;font-size:11px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.05em}.chronos-day{display:flex;align-items:center;justify-content:center;width:36px;height:36px;margin:0 auto;border:none;border-radius:50%;font-size:14px;font-weight:500;color:#1a1a1a;background:transparent;cursor:pointer;transition:all .2s ease;position:relative}.chronos-day:hover:not(.disabled){background:#f3f4f6;transform:scale(1.08)}.chronos-day.other-month{color:#9ca3af}.chronos-day.today{color:#3b82f6;font-weight:600}.chronos-day.today:after{content:"";position:absolute;bottom:5px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:#3b82f6}.chronos-day.selected{background:#3b82f6;color:#fff;font-weight:600;box-shadow:0 2px 8px #3b82f659}.chronos-day.selected:hover{background:#2563eb;box-shadow:0 2px 12px #2563eb66}.chronos-day.disabled{color:#d1d5db;cursor:not-allowed;opacity:.5}.chronos-day.disabled:hover{background:transparent;transform:none}.chronos-day.in-range{background:#e5e7eb;border-radius:0}.chronos-day.in-range:hover{background:#d1d5db}.chronos-day.range-start{border-radius:50% 0 0 50%}.chronos-day.range-start.in-range{background:#e5e7eb}.chronos-day.range-end{border-radius:0 50% 50% 0}.chronos-day.range-end.in-range{background:#e5e7eb}.chronos-day.range-start.selected,.chronos-day.range-end.selected{background:#1a1a1a;color:#fff;font-weight:600;box-shadow:0 0 0 2px #fff}.chronos-day.range-start.selected:hover,.chronos-day.range-end.selected:hover{background:#374151}.chronos-day.range-start.range-end{border-radius:50%}.chronos-day:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.chronos-time-picker{padding:16px}.chronos-dropdown[data-orientation=portrait] .chronos-time-picker{border-top:1px solid #e5e7eb}.chronos-time-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-weight:600;color:#4b5563}.chronos-clock-icon{width:18px;height:18px;color:#6b7280}.chronos-time-controls{display:flex;align-items:flex-end;justify-content:center;gap:8px}.chronos-time-input-group{display:flex;flex-direction:column;gap:4px}.chronos-time-label{font-size:11px;font-weight:500;color:#6b7280;text-transform:uppercase;letter-spacing:.5px}.chronos-time-select{width:70px;padding:8px 10px;border:1.5px solid #d1d5db;border-radius:6px;font-size:16px;font-weight:600;color:#1a1a1a;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none;text-align:center}.chronos-time-select:hover{border-color:#9ca3af}.chronos-time-select:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-time-separator{font-size:24px;font-weight:700;color:#1a1a1a;line-height:1;margin-bottom:8px}.chronos-period-toggle{padding:8px 16px;border:1.5px solid #d1d5db;border-radius:6px;font-size:14px;font-weight:600;color:#1a1a1a;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none}.chronos-period-toggle:hover{border-color:#3b82f6;background-color:#eff6ff;color:#3b82f6}.chronos-period-toggle:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-period-toggle:active{transform:scale(.95)}.chronos-timezone-selector{padding:16px}.chronos-dropdown[data-orientation=portrait] .chronos-timezone-selector{border-top:1px solid #e5e7eb}.chronos-timezone-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-weight:600;color:#4b5563}.chronos-globe-icon{width:18px;height:18px;color:#6b7280}.chronos-timezone-button{display:flex;align-items:center;justify-content:space-between;width:100%;padding:10px 12px;border:1.5px solid #d1d5db;border-radius:8px;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none}.chronos-timezone-button:hover{border-color:#9ca3af}.chronos-timezone-button:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-timezone-label{font-weight:500;color:#1a1a1a;flex:1;text-align:left}.chronos-timezone-offset{font-size:12px;color:#6b7280;margin-right:8px}.chronos-chevron{width:16px;height:16px;color:#6b7280;transition:transform .2s ease}.chronos-chevron.expanded{transform:rotate(180deg)}.chronos-timezone-list{margin-top:8px;max-height:240px;overflow-y:auto;border:1px solid #e5e7eb;border-radius:8px;background:#fff;animation:chronos-timezone-list-appear .2s ease}@keyframes chronos-timezone-list-appear{0%{opacity:0;max-height:0}to{opacity:1;max-height:240px}}.chronos-timezone-option{display:flex;align-items:center;justify-content:space-between;width:100%;padding:10px 12px;border:none;border-bottom:1px solid #f3f4f6;background:transparent;text-align:left;cursor:pointer;transition:background .15s ease;outline:none}.chronos-timezone-option:last-child{border-bottom:none}.chronos-timezone-option:hover{background:#f9fafb}.chronos-timezone-option.selected{background:#eff6ff}.chronos-timezone-option:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.chronos-timezone-option-label{font-weight:500;color:#1a1a1a}.chronos-timezone-option.selected .chronos-timezone-option-label{color:#3b82f6;font-weight:600}.chronos-timezone-option-offset{font-size:12px;color:#6b7280}@media (max-width: 480px){.chronos-dropdown{min-width:calc(100vw - 32px);max-width:calc(100vw - 32px)}.chronos-picker{max-width:100%}}.chronos-timezone-list::-webkit-scrollbar{width:6px}.chronos-timezone-list::-webkit-scrollbar-track{background:#f3f4f6}.chronos-timezone-list::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:3px}.chronos-timezone-list::-webkit-scrollbar-thumb:hover{background:#9ca3af}.chronos-picker[data-theme=dark]{color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=landscape] .chronos-calendar{border-right-color:#374151}.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=landscape] .chronos-time-picker{border-bottom-color:#374151}.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=portrait] .chronos-time-picker,.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=portrait] .chronos-timezone-selector{border-top-color:#374151}.chronos-picker[data-theme=dark] .chronos-input{background-color:#1f2937;border-color:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-input:hover:not(:disabled){border-color:#4b5563}.chronos-picker[data-theme=dark] .chronos-input:disabled{background-color:#111827}.chronos-picker[data-theme=dark] .chronos-input::placeholder{color:#6b7280}.chronos-picker[data-theme=dark] .chronos-calendar-icon{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-dropdown{background:#1f2937;border-color:#374151;box-shadow:0 10px 40px #0006}.chronos-picker[data-theme=dark] .chronos-nav-button{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-nav-button:hover{background:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-month-select,.chronos-picker[data-theme=dark] .chronos-year-select{background-color:#1f2937;border-color:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-weekday{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-day{color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-day:hover:not(.disabled){background:#374151}.chronos-picker[data-theme=dark] .chronos-day.other-month{color:#6b7280}.chronos-picker[data-theme=dark] .chronos-day.today{color:#60a5fa}.chronos-picker[data-theme=dark] .chronos-day.today:after{background:#60a5fa}.chronos-picker[data-theme=dark] .chronos-day.selected{background:#3b82f6;color:#fff}.chronos-picker[data-theme=dark] .chronos-range-nights{color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-range-dates{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-day.in-range{background:#374151}.chronos-picker[data-theme=dark] .chronos-day.in-range:hover{background:#4b5563}.chronos-picker[data-theme=dark] .chronos-day.range-start.selected,.chronos-picker[data-theme=dark] .chronos-day.range-end.selected{background:#3b82f6;color:#fff;box-shadow:0 0 0 2px #1f2937}.chronos-picker[data-theme=dark] .chronos-time-header,.chronos-picker[data-theme=dark] .chronos-timezone-header{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-time-select,.chronos-picker[data-theme=dark] .chronos-period-toggle,.chronos-picker[data-theme=dark] .chronos-timezone-button{background-color:#1f2937;border-color:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-timezone-list{background:#1f2937;border-color:#374151}.chronos-picker[data-theme=dark] .chronos-timezone-option:hover{background:#374151}.chronos-picker[data-theme=dark] .chronos-timezone-option.selected{background:#1e3a5f}.chronos-picker[data-theme=dark] .chronos-timezone-option.selected .chronos-timezone-option-label{color:#60a5fa}
|
|
1
|
+
.chronos-picker{position:relative;display:inline-block;width:100%;max-width:320px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;color:#1a1a1a}.chronos-picker[data-disabled=true]{opacity:.6;cursor:not-allowed}.chronos-input-wrapper{position:relative;display:flex;align-items:center;cursor:pointer}.chronos-input{width:100%;padding:10px 40px 10px 14px;border:1.5px solid #d1d5db;border-radius:8px;font-size:14px;color:#1a1a1a;background-color:#fff;transition:all .2s ease;cursor:pointer;outline:none}.chronos-input:hover:not(:disabled){border-color:#9ca3af}.chronos-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-input:disabled{background-color:#f3f4f6;cursor:not-allowed}.chronos-input::placeholder{color:#9ca3af}.chronos-calendar-icon{position:absolute;right:12px;width:20px;height:20px;color:#6b7280;pointer-events:none;transition:color .2s ease}.chronos-input:hover:not(:disabled)~.chronos-calendar-icon,.chronos-input:focus~.chronos-calendar-icon{color:#3b82f6}.chronos-dropdown{position:absolute;top:calc(100% + 8px);left:0;z-index:99999;min-width:320px;background:#fff;border:1px solid #e5e7eb;border-radius:14px;box-shadow:0 4px 6px -1px #00000014,0 10px 30px -4px #0000001f;overflow:hidden;animation:chronos-dropdown-appear .2s ease}.chronos-dropdown-content{display:flex;flex-direction:column}.chronos-dropdown[data-orientation=portrait] .chronos-dropdown-content{flex-direction:column}.chronos-dropdown[data-orientation=landscape]{min-width:auto}.chronos-dropdown[data-orientation=landscape] .chronos-dropdown-content{flex-direction:row}.chronos-dropdown[data-orientation=landscape] .chronos-calendar{border-right:1px solid #e5e7eb;border-bottom:none}.chronos-dropdown[data-orientation=landscape] .chronos-sidebar{display:flex;flex-direction:column;min-width:240px}.chronos-dropdown[data-orientation=landscape] .chronos-time-picker{border-top:none;border-bottom:1px solid #e5e7eb}.chronos-dropdown[data-orientation=landscape] .chronos-time-picker:last-child{border-bottom:none}.chronos-dropdown[data-orientation=landscape] .chronos-timezone-selector{border-top:none}@keyframes chronos-dropdown-appear{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.chronos-range-summary{padding:16px 16px 0;margin-bottom:8px}.chronos-range-nights{font-size:1.5rem;font-weight:700;color:#1a1a1a;letter-spacing:-.025em;line-height:1.2}.chronos-range-dates{font-size:.875rem;color:#6b7280;margin-top:4px}.chronos-calendar{padding:16px}.chronos-calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;gap:8px}.chronos-nav-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:#4b5563;font-size:20px;font-weight:600;cursor:pointer;transition:all .15s ease}.chronos-nav-button:hover{background:#f3f4f6;color:#1a1a1a}.chronos-nav-button:active{transform:scale(.95)}.chronos-month-year-selectors{display:flex;gap:8px;flex:1;justify-content:center}.chronos-month-select,.chronos-year-select{padding:6px 10px;border:1px solid #d1d5db;border-radius:6px;font-size:14px;font-weight:500;color:#1a1a1a;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none}.chronos-month-select:hover,.chronos-year-select:hover{border-color:#9ca3af}.chronos-month-select:focus,.chronos-year-select:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-calendar-grid{display:flex;flex-direction:column;gap:4px}.chronos-weekday-row,.chronos-week-row{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.chronos-weekday{display:flex;align-items:center;justify-content:center;height:32px;font-size:11px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.05em}.chronos-day{display:flex;align-items:center;justify-content:center;width:36px;height:36px;margin:0 auto;border:none;border-radius:50%;font-size:14px;font-weight:500;color:#1a1a1a;background:transparent;cursor:pointer;transition:all .2s ease;position:relative}.chronos-day:hover:not(.disabled){background:#f3f4f6;transform:scale(1.08)}.chronos-day.other-month{color:#9ca3af}.chronos-day.today{color:#3b82f6;font-weight:600}.chronos-day.today:after{content:"";position:absolute;bottom:5px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:#3b82f6}.chronos-day.selected{background:#3b82f6;color:#fff;font-weight:600;box-shadow:0 2px 8px #3b82f659}.chronos-day.selected:hover{background:#2563eb;box-shadow:0 2px 12px #2563eb66}.chronos-day.disabled{color:#d1d5db;cursor:not-allowed;opacity:.5}.chronos-day.disabled:hover{background:transparent;transform:none}.chronos-day.in-range{background:#e5e7eb;border-radius:0}.chronos-day.in-range:hover{background:#d1d5db}.chronos-day.range-start{border-radius:50% 0 0 50%}.chronos-day.range-start.in-range{background:#e5e7eb}.chronos-day.range-end{border-radius:0 50% 50% 0}.chronos-day.range-end.in-range{background:#e5e7eb}.chronos-day.range-start.selected,.chronos-day.range-end.selected{background:#1a1a1a;color:#fff;font-weight:600;box-shadow:0 0 0 2px #fff}.chronos-day.range-start.selected:hover,.chronos-day.range-end.selected:hover{background:#374151}.chronos-day.range-start.range-end{border-radius:50%}.chronos-day:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.chronos-time-picker{padding:16px}.chronos-dropdown[data-orientation=portrait] .chronos-time-picker{border-top:1px solid #e5e7eb}.chronos-time-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-weight:600;color:#4b5563}.chronos-clock-icon{width:18px;height:18px;color:#6b7280}.chronos-time-controls{display:flex;align-items:flex-end;justify-content:center;gap:8px}.chronos-time-input-group{display:flex;flex-direction:column;gap:4px}.chronos-time-label{font-size:11px;font-weight:500;color:#6b7280;text-transform:uppercase;letter-spacing:.5px}.chronos-time-select{width:70px;padding:8px 10px;border:1.5px solid #d1d5db;border-radius:6px;font-size:16px;font-weight:600;color:#1a1a1a;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none;text-align:center}.chronos-time-select:hover{border-color:#9ca3af}.chronos-time-select:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-time-separator{font-size:24px;font-weight:700;color:#1a1a1a;line-height:1;margin-bottom:8px}.chronos-period-toggle{padding:8px 16px;border:1.5px solid #d1d5db;border-radius:6px;font-size:14px;font-weight:600;color:#1a1a1a;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none}.chronos-period-toggle:hover{border-color:#3b82f6;background-color:#eff6ff;color:#3b82f6}.chronos-period-toggle:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-period-toggle:active{transform:scale(.95)}.chronos-timezone-selector{padding:16px}.chronos-dropdown[data-orientation=portrait] .chronos-timezone-selector{border-top:1px solid #e5e7eb}.chronos-timezone-header{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-weight:600;color:#4b5563}.chronos-globe-icon{width:18px;height:18px;color:#6b7280}.chronos-timezone-button{display:flex;align-items:center;justify-content:space-between;width:100%;padding:10px 12px;border:1.5px solid #d1d5db;border-radius:8px;background-color:#fff;cursor:pointer;transition:all .15s ease;outline:none}.chronos-timezone-button:hover{border-color:#9ca3af}.chronos-timezone-button:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.chronos-timezone-label{font-weight:500;color:#1a1a1a;flex:1;text-align:left}.chronos-timezone-offset{font-size:12px;color:#6b7280;margin-right:8px}.chronos-chevron{width:16px;height:16px;color:#6b7280;transition:transform .2s ease}.chronos-chevron.expanded{transform:rotate(180deg)}.chronos-timezone-list{margin-top:8px;max-height:240px;overflow-y:auto;border:1px solid #e5e7eb;border-radius:8px;background:#fff;animation:chronos-timezone-list-appear .2s ease}@keyframes chronos-timezone-list-appear{0%{opacity:0;max-height:0}to{opacity:1;max-height:240px}}.chronos-timezone-option{display:flex;align-items:center;justify-content:space-between;width:100%;padding:10px 12px;border:none;border-bottom:1px solid #f3f4f6;background:transparent;text-align:left;cursor:pointer;transition:background .15s ease;outline:none}.chronos-timezone-option:last-child{border-bottom:none}.chronos-timezone-option:hover{background:#f9fafb}.chronos-timezone-option.selected{background:#eff6ff}.chronos-timezone-option:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.chronos-timezone-option-label{font-weight:500;color:#1a1a1a}.chronos-timezone-option.selected .chronos-timezone-option-label{color:#3b82f6;font-weight:600}.chronos-timezone-option-offset{font-size:12px;color:#6b7280}@media (max-width: 480px){.chronos-dropdown{min-width:calc(100vw - 32px);max-width:calc(100vw - 32px)}.chronos-picker{max-width:100%}}.chronos-timezone-list::-webkit-scrollbar{width:6px}.chronos-timezone-list::-webkit-scrollbar-track{background:#f3f4f6}.chronos-timezone-list::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:3px}.chronos-timezone-list::-webkit-scrollbar-thumb:hover{background:#9ca3af}.chronos-picker[data-theme=dark]{color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=landscape] .chronos-calendar{border-right-color:#374151}.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=landscape] .chronos-time-picker{border-bottom-color:#374151}.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=portrait] .chronos-time-picker,.chronos-picker[data-theme=dark] .chronos-dropdown[data-orientation=portrait] .chronos-timezone-selector{border-top-color:#374151}.chronos-picker[data-theme=dark] .chronos-input{background-color:#1f2937;border-color:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-input:hover:not(:disabled){border-color:#4b5563}.chronos-picker[data-theme=dark] .chronos-input:disabled{background-color:#111827}.chronos-picker[data-theme=dark] .chronos-input::placeholder{color:#6b7280}.chronos-picker[data-theme=dark] .chronos-calendar-icon{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-dropdown{background:#1f2937;border-color:#374151;box-shadow:0 10px 40px #0006}.chronos-picker[data-theme=dark] .chronos-nav-button{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-nav-button:hover{background:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-month-select,.chronos-picker[data-theme=dark] .chronos-year-select{background-color:#1f2937;border-color:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-weekday{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-day{color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-day:hover:not(.disabled){background:#374151}.chronos-picker[data-theme=dark] .chronos-day.other-month{color:#6b7280}.chronos-picker[data-theme=dark] .chronos-day.today{color:#60a5fa}.chronos-picker[data-theme=dark] .chronos-day.today:after{background:#60a5fa}.chronos-picker[data-theme=dark] .chronos-day.selected{background:#3b82f6;color:#fff}.chronos-picker[data-theme=dark] .chronos-range-nights{color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-range-dates{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-day.in-range{background:#374151}.chronos-picker[data-theme=dark] .chronos-day.in-range:hover{background:#4b5563}.chronos-picker[data-theme=dark] .chronos-day.range-start.selected,.chronos-picker[data-theme=dark] .chronos-day.range-end.selected{background:#3b82f6;color:#fff;box-shadow:0 0 0 2px #1f2937}.chronos-picker[data-theme=dark] .chronos-time-header,.chronos-picker[data-theme=dark] .chronos-timezone-header{color:#9ca3af}.chronos-picker[data-theme=dark] .chronos-time-select,.chronos-picker[data-theme=dark] .chronos-period-toggle,.chronos-picker[data-theme=dark] .chronos-timezone-button{background-color:#1f2937;border-color:#374151;color:#f3f4f6}.chronos-picker[data-theme=dark] .chronos-timezone-list{background:#1f2937;border-color:#374151}.chronos-picker[data-theme=dark] .chronos-timezone-option:hover{background:#374151}.chronos-picker[data-theme=dark] .chronos-timezone-option.selected{background:#1e3a5f}.chronos-picker[data-theme=dark] .chronos-timezone-option.selected .chronos-timezone-option-label{color:#60a5fa}
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@theengineerguy/chronos-picker",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "A modern, accessible date & time picker with comprehensive timezone support",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.esm.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
],
|
|
11
|
-
"scripts": {
|
|
12
|
-
"dev": "vite",
|
|
13
|
-
"build": "tsc && vite build",
|
|
14
|
-
"lint": "eslint src --ext ts,tsx",
|
|
15
|
-
"test": "vitest",
|
|
16
|
-
"prepublishOnly": "npm run build",
|
|
17
|
-
"publish:npm": "npm publish --access public"
|
|
18
|
-
},
|
|
19
|
-
"keywords": [
|
|
20
|
-
"datepicker",
|
|
21
|
-
"timepicker",
|
|
22
|
-
"datetime",
|
|
23
|
-
"timezone",
|
|
24
|
-
"react",
|
|
25
|
-
"component",
|
|
26
|
-
"accessible",
|
|
27
|
-
"a11y"
|
|
28
|
-
],
|
|
29
|
-
"author": "Debmalya Biswas <viperbale.db.@gmail.com>",
|
|
30
|
-
"license": "MIT",
|
|
31
|
-
"homepage": "https://
|
|
32
|
-
"bugs": {
|
|
33
|
-
"url": "https://github.com/AnTIdoTe003/chronos-picker/issues"
|
|
34
|
-
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"react": "^18.0.0 || ^19.0.0",
|
|
37
|
-
"react-dom": "^18.0.0 || ^19.0.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"luxon": "^3.4.4"
|
|
41
|
-
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"@types/luxon": "^3.4.2",
|
|
44
|
-
"@types/node": "^25.2.3",
|
|
45
|
-
"@types/react": "^18.2.48",
|
|
46
|
-
"@types/react-dom": "^18.2.18",
|
|
47
|
-
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
48
|
-
"@typescript-eslint/parser": "^6.19.0",
|
|
49
|
-
"@vitejs/plugin-react": "^4.2.1",
|
|
50
|
-
"eslint": "^8.56.0",
|
|
51
|
-
"eslint-plugin-react-hooks": "^4.6.0",
|
|
52
|
-
"typescript": "^5.3.3",
|
|
53
|
-
"vite": "^5.0.11",
|
|
54
|
-
"vite-plugin-dts": "^3.7.1",
|
|
55
|
-
"vitest": "^1.2.1"
|
|
56
|
-
},
|
|
57
|
-
"repository": {
|
|
58
|
-
"type": "git",
|
|
59
|
-
"url": "https://github.com/AnTIdoTe003/chronos-picker"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@theengineerguy/chronos-picker",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "A modern, accessible date & time picker with comprehensive timezone support",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"build": "tsc && vite build",
|
|
14
|
+
"lint": "eslint src --ext ts,tsx",
|
|
15
|
+
"test": "vitest",
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"publish:npm": "npm publish --access public"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"datepicker",
|
|
21
|
+
"timepicker",
|
|
22
|
+
"datetime",
|
|
23
|
+
"timezone",
|
|
24
|
+
"react",
|
|
25
|
+
"component",
|
|
26
|
+
"accessible",
|
|
27
|
+
"a11y"
|
|
28
|
+
],
|
|
29
|
+
"author": "Debmalya Biswas <viperbale.db.@gmail.com>",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"homepage": "https://chronos-picker.debmalya.in",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/AnTIdoTe003/chronos-picker/issues"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
37
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"luxon": "^3.4.4"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/luxon": "^3.4.2",
|
|
44
|
+
"@types/node": "^25.2.3",
|
|
45
|
+
"@types/react": "^18.2.48",
|
|
46
|
+
"@types/react-dom": "^18.2.18",
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
48
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
49
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
50
|
+
"eslint": "^8.56.0",
|
|
51
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
52
|
+
"typescript": "^5.3.3",
|
|
53
|
+
"vite": "^5.0.11",
|
|
54
|
+
"vite-plugin-dts": "^3.7.1",
|
|
55
|
+
"vitest": "^1.2.1"
|
|
56
|
+
},
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "https://github.com/AnTIdoTe003/chronos-picker"
|
|
60
|
+
}
|
|
61
|
+
}
|