@delightui/components 0.1.104 → 0.1.106

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.
Files changed (120) hide show
  1. package/README.md +104 -1
  2. package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
  3. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  4. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  5. package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  6. package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  7. package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
  8. package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  9. package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
  10. package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
  11. package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
  12. package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
  13. package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
  14. package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
  15. package/dist/cjs/components/molecules/index.d.ts +2 -0
  16. package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
  17. package/dist/cjs/components/utils/index.d.ts +2 -0
  18. package/dist/cjs/library.css +13 -0
  19. package/dist/cjs/library.js +2 -2
  20. package/dist/cjs/library.js.map +1 -1
  21. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  22. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  23. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  24. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  25. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  26. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  27. package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  28. package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
  29. package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
  30. package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
  31. package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
  32. package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
  33. package/dist/esm/components/molecules/Select/index.d.ts +2 -9
  34. package/dist/esm/components/molecules/index.d.ts +2 -0
  35. package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
  36. package/dist/esm/components/utils/index.d.ts +2 -0
  37. package/dist/esm/library.css +13 -0
  38. package/dist/esm/library.js +3 -3
  39. package/dist/esm/library.js.map +1 -1
  40. package/dist/index.d.ts +156 -12
  41. package/docs/README.md +264 -0
  42. package/docs/components/atoms/ActionImage.md +119 -0
  43. package/docs/components/atoms/Button.md +197 -0
  44. package/docs/components/atoms/Checkbox.md +299 -0
  45. package/docs/components/atoms/CheckboxItem.md +314 -0
  46. package/docs/components/atoms/Chip.md +380 -0
  47. package/docs/components/atoms/CustomToggle.md +270 -0
  48. package/docs/components/atoms/Icon.md +365 -0
  49. package/docs/components/atoms/IconButton.md +407 -0
  50. package/docs/components/atoms/Image.md +448 -0
  51. package/docs/components/atoms/Input.md +430 -0
  52. package/docs/components/atoms/ListItem.md +502 -0
  53. package/docs/components/atoms/Password.md +472 -0
  54. package/docs/components/atoms/RadioButton.md +614 -0
  55. package/docs/components/atoms/RadioButtonItem.md +588 -0
  56. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  57. package/docs/components/atoms/SelectListItem.md +609 -0
  58. package/docs/components/atoms/Slider.md +605 -0
  59. package/docs/components/atoms/Spinner.md +605 -0
  60. package/docs/components/atoms/Text.md +463 -0
  61. package/docs/components/atoms/TextArea.md +670 -0
  62. package/docs/components/atoms/ToastNotification.md +668 -0
  63. package/docs/components/atoms/Toggle.md +737 -0
  64. package/docs/components/atoms/ToggleButton.md +751 -0
  65. package/docs/components/atoms/Tooltip.md +391 -0
  66. package/docs/components/molecules/Accordion.md +440 -0
  67. package/docs/components/molecules/AccordionGroup.md +547 -0
  68. package/docs/components/molecules/ActionCard.md +546 -0
  69. package/docs/components/molecules/Breadcrumb.md +403 -0
  70. package/docs/components/molecules/Breadcrumbs.md +485 -0
  71. package/docs/components/molecules/ButtonGroup.md +383 -0
  72. package/docs/components/molecules/Card.md +298 -0
  73. package/docs/components/molecules/ChipInput.md +646 -0
  74. package/docs/components/molecules/ContextMenu.md +768 -0
  75. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  76. package/docs/components/molecules/DatePicker.md +516 -0
  77. package/docs/components/molecules/DateTimeSelector.md +166 -0
  78. package/docs/components/molecules/FormField.md +312 -0
  79. package/docs/components/molecules/Grid.md +577 -0
  80. package/docs/components/molecules/GridItem.md +834 -0
  81. package/docs/components/molecules/GridList.md +244 -0
  82. package/docs/components/molecules/List.md +485 -0
  83. package/docs/components/molecules/Modal.md +470 -0
  84. package/docs/components/molecules/ModalFooter.md +702 -0
  85. package/docs/components/molecules/ModalHeader.md +756 -0
  86. package/docs/components/molecules/ModalProvider.md +205 -0
  87. package/docs/components/molecules/Nav.md +530 -0
  88. package/docs/components/molecules/NavItem.md +572 -0
  89. package/docs/components/molecules/NavLink.md +499 -0
  90. package/docs/components/molecules/Option.md +521 -0
  91. package/docs/components/molecules/Pagination.md +592 -0
  92. package/docs/components/molecules/PaginationNumberField.md +722 -0
  93. package/docs/components/molecules/Popover.md +516 -0
  94. package/docs/components/molecules/ProgressBar.md +624 -0
  95. package/docs/components/molecules/RadioGroup.md +831 -0
  96. package/docs/components/molecules/RepeaterList.md +185 -0
  97. package/docs/components/molecules/Select.md +402 -0
  98. package/docs/components/molecules/SortableTrigger.md +82 -0
  99. package/docs/components/molecules/useModal.md +379 -0
  100. package/docs/components/organisms/Dropzone.md +346 -0
  101. package/docs/components/organisms/DropzoneClear.md +135 -0
  102. package/docs/components/organisms/DropzoneContent.md +216 -0
  103. package/docs/components/organisms/DropzoneFilename.md +191 -0
  104. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  105. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  106. package/docs/components/organisms/Form.md +533 -0
  107. package/docs/components/organisms/SlideOutPanel.md +662 -0
  108. package/docs/components/organisms/TabContent.md +902 -0
  109. package/docs/components/organisms/TabItem.md +1091 -0
  110. package/docs/components/organisms/Table.md +611 -0
  111. package/docs/components/organisms/TableBody.md +679 -0
  112. package/docs/components/organisms/TableCell.md +482 -0
  113. package/docs/components/organisms/TableHeader.md +513 -0
  114. package/docs/components/organisms/TableHeaderCell.md +661 -0
  115. package/docs/components/organisms/TableRow.md +715 -0
  116. package/docs/components/organisms/Tabs.md +1330 -0
  117. package/docs/components/utils/ConditionalView.md +568 -0
  118. package/docs/components/utils/RenderStateView.md +726 -0
  119. package/docs/components/utils/WrapTextNodes.md +614 -0
  120. package/package.json +3 -2
@@ -0,0 +1,116 @@
1
+ # CustomTimeSelector
2
+
3
+ ## Description
4
+
5
+ A Flatpickr plugin component that provides a custom time selection interface with dropdown functionality. It creates an enhanced time input field with a searchable time options dropdown, replacing the default Flatpickr time picker with a more user-friendly time selection experience.
6
+
7
+ ## Aliases
8
+
9
+ - CustomTimeSelector
10
+ - TimeDropdownPlugin
11
+ - TimePickerPlugin
12
+ - CustomTimePicker
13
+
14
+ ## Props Breakdown
15
+
16
+ **Type:** Flatpickr Plugin Function
17
+
18
+ | Prop | Type | Default | Required | Description |
19
+ |------|------|---------|----------|-------------|
20
+ | `config` | `CustomTimePickerConfig` | - | Yes | Configuration object for the time picker |
21
+ | `config.minuteStep` | `number` | `30` | No | Step interval for minute options in the dropdown |
22
+
23
+ ## Examples
24
+
25
+ ### Basic Usage
26
+ ```tsx
27
+ import { DatePicker } from '@delightui/components';
28
+ import customTimeSelector from './Plugins/customTimeSelector';
29
+
30
+ function TimePickerExample() {
31
+ return (
32
+ <DatePicker
33
+ plugins={[customTimeSelector({ minuteStep: 15 })]}
34
+ enableTime={true}
35
+ noCalendar={true}
36
+ dateFormat="h:i K"
37
+ />
38
+ );
39
+ }
40
+ ```
41
+
42
+ ### Custom Minute Steps
43
+ ```tsx
44
+ function CustomStepsExample() {
45
+ return (
46
+ <div className="time-pickers">
47
+ {/* 15-minute intervals */}
48
+ <DatePicker
49
+ plugins={[customTimeSelector({ minuteStep: 15 })]}
50
+ enableTime={true}
51
+ noCalendar={true}
52
+ placeholder="Select time (15 min steps)"
53
+ />
54
+
55
+ {/* 5-minute intervals */}
56
+ <DatePicker
57
+ plugins={[customTimeSelector({ minuteStep: 5 })]}
58
+ enableTime={true}
59
+ noCalendar={true}
60
+ placeholder="Select time (5 min steps)"
61
+ />
62
+
63
+ {/* 1-hour intervals */}
64
+ <DatePicker
65
+ plugins={[customTimeSelector({ minuteStep: 60 })]}
66
+ enableTime={true}
67
+ noCalendar={true}
68
+ placeholder="Select time (hourly)"
69
+ />
70
+ </div>
71
+ );
72
+ }
73
+ ```
74
+
75
+ ### With Date and Time
76
+ ```tsx
77
+ function DateTimeExample() {
78
+ return (
79
+ <DatePicker
80
+ plugins={[customTimeSelector({ minuteStep: 30 })]}
81
+ enableTime={true}
82
+ dateFormat="m/d/Y h:i K"
83
+ placeholder="Select date and time"
84
+ />
85
+ );
86
+ }
87
+ ```
88
+
89
+ ### Form Integration
90
+ ```tsx
91
+ import { Form, FormField, DatePicker } from '@delightui/components';
92
+
93
+ function FormTimeExample() {
94
+ const handleSubmit = (values) => {
95
+ console.log('Selected time:', values.appointmentTime);
96
+ };
97
+
98
+ return (
99
+ <Form onSubmit={handleSubmit}>
100
+ <FormField
101
+ name="appointmentTime"
102
+ label="Appointment Time"
103
+ required
104
+ >
105
+ <DatePicker
106
+ plugins={[customTimeSelector({ minuteStep: 15 })]}
107
+ enableTime={true}
108
+ noCalendar={true}
109
+ dateFormat="h:i K"
110
+ placeholder="Select appointment time"
111
+ />
112
+ </FormField>
113
+ </Form>
114
+ );
115
+ }
116
+ ```
@@ -0,0 +1,516 @@
1
+ # DatePicker
2
+
3
+ ## Description
4
+
5
+ A comprehensive date and time selection component built on Flatpickr with extensive customization options. Supports single date selection, date ranges, time selection, inline display, and custom positioning. Includes advanced features like custom time pickers, date parsing, and keyboard navigation for flexible date/time input scenarios.
6
+
7
+ ## Aliases
8
+
9
+ - DatePicker
10
+ - DateSelector
11
+ - Calendar
12
+ - DateInput
13
+ - DateTimePicker
14
+
15
+ ## Props Breakdown
16
+
17
+ **Extends:** ControlledFormComponentProps<DatePickerValue> (form field integration)
18
+
19
+ | Prop | Type | Default | Required | Description |
20
+ |------|------|---------|----------|-------------|
21
+ | `value` | `DatePickerValue` | - | No | Current selected date(s) - string, Date, or array |
22
+ | `onChange` | `(value: DatePickerValue) => void` | - | No | Callback fired when date selection changes |
23
+ | `minDate` | `string \| Date` | - | No | Minimum selectable date |
24
+ | `maxDate` | `string \| Date` | - | No | Maximum selectable date |
25
+ | `enableTime` | `boolean` | `false` | No | Enable time selection in addition to date |
26
+ | `enableRange` | `boolean` | `false` | No | Enable selecting date ranges (start and end) |
27
+ | `defaultDate` | `string \| Date` | - | No | Initially displayed date when picker opens |
28
+ | `dateFormat` | `string` | - | No | Display format for selected dates (Flatpickr format) |
29
+ | `onOpen` | `(dates: Date[], dateStr: string) => void` | - | No | Callback fired when picker opens |
30
+ | `onClose` | `(dates: Date[], dateStr: string) => void` | - | No | Callback fired when picker closes |
31
+ | `inline` | `boolean` | `false` | No | Render picker inline instead of as popup |
32
+ | `noCalendar` | `boolean` | `false` | No | Hide calendar for time-only selection |
33
+ | `position` | `DatePickerPosition` | `'auto'` | No | Positioning of the picker popup |
34
+ | `parseDate` | `(date: string, format?: string) => Date` | - | No | Custom date parsing function |
35
+ | `allowInput` | `boolean` | `false` | No | Allow manual typing in input field |
36
+ | `placeholder` | `string` | - | No | Placeholder text for input |
37
+ | `leadingIcon` | `ReactNode` | - | No | Icon displayed before input |
38
+ | `trailingIcon` | `ReactNode` | - | No | Icon displayed after input |
39
+ | `className` | `string` | - | No | Additional CSS class names |
40
+
41
+ ## Examples
42
+
43
+ ### Basic Date Picker
44
+ ```tsx
45
+ import { DatePicker, FormField } from '@delightui/components';
46
+
47
+ function BasicExample() {
48
+ const [selectedDate, setSelectedDate] = useState(null);
49
+
50
+ return (
51
+ <FormField label="Select Date">
52
+ <DatePicker
53
+ value={selectedDate}
54
+ onChange={setSelectedDate}
55
+ placeholder="Choose a date..."
56
+ leadingIcon={<Icon icon="Calendar" />}
57
+ />
58
+ </FormField>
59
+ );
60
+ }
61
+ ```
62
+
63
+ ### Date Range Picker
64
+ ```tsx
65
+ function DateRangeExample() {
66
+ const [dateRange, setDateRange] = useState([]);
67
+
68
+ return (
69
+ <div className="date-range-form">
70
+ <FormField label="Select Date Range">
71
+ <DatePicker
72
+ value={dateRange}
73
+ onChange={setDateRange}
74
+ enableRange={true}
75
+ placeholder="Select start and end dates..."
76
+ dateFormat="Y-m-d"
77
+ leadingIcon={<Icon icon="DateRange" />}
78
+ />
79
+ </FormField>
80
+
81
+ {dateRange.length === 2 && (
82
+ <div className="range-display">
83
+ <Text type="BodySmall">
84
+ From: {dateRange[0]?.toLocaleDateString()}
85
+ To: {dateRange[1]?.toLocaleDateString()}
86
+ </Text>
87
+ </div>
88
+ )}
89
+ </div>
90
+ );
91
+ }
92
+ ```
93
+
94
+ ### Date and Time Picker
95
+ ```tsx
96
+ function DateTimeExample() {
97
+ const [dateTime, setDateTime] = useState(null);
98
+
99
+ return (
100
+ <FormField label="Appointment Date & Time">
101
+ <DatePicker
102
+ value={dateTime}
103
+ onChange={setDateTime}
104
+ enableTime={true}
105
+ dateFormat="Y-m-d H:i"
106
+ placeholder="Select date and time..."
107
+ leadingIcon={<Icon icon="Schedule" />}
108
+ />
109
+ </FormField>
110
+ );
111
+ }
112
+ ```
113
+
114
+ ### Time Only Picker
115
+ ```tsx
116
+ function TimeOnlyExample() {
117
+ const [time, setTime] = useState(null);
118
+
119
+ return (
120
+ <FormField label="Meeting Time">
121
+ <DatePicker
122
+ value={time}
123
+ onChange={setTime}
124
+ enableTime={true}
125
+ noCalendar={true}
126
+ dateFormat="H:i"
127
+ placeholder="Select time..."
128
+ leadingIcon={<Icon icon="AccessTime" />}
129
+ />
130
+ </FormField>
131
+ );
132
+ }
133
+ ```
134
+
135
+ ### Inline Calendar
136
+ ```tsx
137
+ function InlineCalendarExample() {
138
+ const [selectedDate, setSelectedDate] = useState(new Date());
139
+
140
+ return (
141
+ <div className="inline-calendar-container">
142
+ <Text type="Heading5">Choose Your Date</Text>
143
+
144
+ <DatePicker
145
+ value={selectedDate}
146
+ onChange={setSelectedDate}
147
+ inline={true}
148
+ dateFormat="F j, Y"
149
+ />
150
+
151
+ {selectedDate && (
152
+ <div className="selected-date-display">
153
+ <Text>Selected: {selectedDate.toLocaleDateString()}</Text>
154
+ </div>
155
+ )}
156
+ </div>
157
+ );
158
+ }
159
+ ```
160
+
161
+ ### Booking System Date Picker
162
+ ```tsx
163
+ function BookingSystemExample() {
164
+ const [checkIn, setCheckIn] = useState(null);
165
+ const [checkOut, setCheckOut] = useState(null);
166
+
167
+ const today = new Date();
168
+ const maxDate = new Date();
169
+ maxDate.setFullYear(today.getFullYear() + 1);
170
+
171
+ const handleCheckInChange = (date) => {
172
+ setCheckIn(date);
173
+ // Clear check-out if it's before new check-in
174
+ if (checkOut && date && new Date(date) >= new Date(checkOut)) {
175
+ setCheckOut(null);
176
+ }
177
+ };
178
+
179
+ return (
180
+ <div className="booking-form">
181
+ <div className="date-inputs">
182
+ <FormField label="Check-in Date" required>
183
+ <DatePicker
184
+ value={checkIn}
185
+ onChange={handleCheckInChange}
186
+ minDate={today}
187
+ maxDate={maxDate}
188
+ placeholder="Select check-in..."
189
+ leadingIcon={<Icon icon="CheckIn" />}
190
+ />
191
+ </FormField>
192
+
193
+ <FormField label="Check-out Date" required>
194
+ <DatePicker
195
+ value={checkOut}
196
+ onChange={setCheckOut}
197
+ minDate={checkIn ? new Date(new Date(checkIn).getTime() + 86400000) : today}
198
+ maxDate={maxDate}
199
+ placeholder="Select check-out..."
200
+ leadingIcon={<Icon icon="CheckOut" />}
201
+ disabled={!checkIn}
202
+ />
203
+ </FormField>
204
+ </div>
205
+
206
+ {checkIn && checkOut && (
207
+ <div className="stay-summary">
208
+ <Text type="Heading6">Stay Summary</Text>
209
+ <Text>
210
+ {Math.ceil((new Date(checkOut) - new Date(checkIn)) / (1000 * 60 * 60 * 24))} nights
211
+ </Text>
212
+ </div>
213
+ )}
214
+ </div>
215
+ );
216
+ }
217
+ ```
218
+
219
+ ### Event Scheduler
220
+ ```tsx
221
+ function EventSchedulerExample() {
222
+ const [eventDate, setEventDate] = useState(null);
223
+ const [startTime, setStartTime] = useState(null);
224
+ const [endTime, setEndTime] = useState(null);
225
+
226
+ const businessHours = {
227
+ minTime: '09:00',
228
+ maxTime: '18:00'
229
+ };
230
+
231
+ return (
232
+ <Form className="event-form">
233
+ <FormField label="Event Date" required>
234
+ <DatePicker
235
+ value={eventDate}
236
+ onChange={setEventDate}
237
+ minDate={new Date()}
238
+ placeholder="Select event date..."
239
+ leadingIcon={<Icon icon="Event" />}
240
+ />
241
+ </FormField>
242
+
243
+ <div className="time-fields">
244
+ <FormField label="Start Time" required>
245
+ <DatePicker
246
+ value={startTime}
247
+ onChange={setStartTime}
248
+ enableTime={true}
249
+ noCalendar={true}
250
+ dateFormat="H:i"
251
+ placeholder="Start time..."
252
+ leadingIcon={<Icon icon="PlayArrow" />}
253
+ />
254
+ </FormField>
255
+
256
+ <FormField label="End Time" required>
257
+ <DatePicker
258
+ value={endTime}
259
+ onChange={setEndTime}
260
+ enableTime={true}
261
+ noCalendar={true}
262
+ dateFormat="H:i"
263
+ placeholder="End time..."
264
+ leadingIcon={<Icon icon="Stop" />}
265
+ minDate={startTime}
266
+ />
267
+ </FormField>
268
+ </div>
269
+
270
+ <Button
271
+ actionType="submit"
272
+ disabled={!eventDate || !startTime || !endTime}
273
+ >
274
+ Schedule Event
275
+ </Button>
276
+ </Form>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ### Deadline Tracker
282
+ ```tsx
283
+ function DeadlineTrackerExample() {
284
+ const [deadlines, setDeadlines] = useState([
285
+ { id: 1, title: 'Project Proposal', date: '2024-02-15' },
286
+ { id: 2, title: 'Final Report', date: '2024-03-01' }
287
+ ]);
288
+ const [newDeadline, setNewDeadline] = useState({ title: '', date: null });
289
+
290
+ const addDeadline = () => {
291
+ if (newDeadline.title && newDeadline.date) {
292
+ setDeadlines(prev => [...prev, {
293
+ id: Date.now(),
294
+ title: newDeadline.title,
295
+ date: newDeadline.date
296
+ }]);
297
+ setNewDeadline({ title: '', date: null });
298
+ }
299
+ };
300
+
301
+ const getDaysUntil = (date) => {
302
+ const today = new Date();
303
+ const deadlineDate = new Date(date);
304
+ const diffTime = deadlineDate - today;
305
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
306
+ return diffDays;
307
+ };
308
+
309
+ return (
310
+ <div className="deadline-tracker">
311
+ <div className="add-deadline">
312
+ <Text type="Heading5">Add New Deadline</Text>
313
+
314
+ <FormField label="Task Title">
315
+ <Input
316
+ value={newDeadline.title}
317
+ onChange={(e) => setNewDeadline(prev => ({ ...prev, title: e.target.value }))}
318
+ placeholder="Enter task title..."
319
+ />
320
+ </FormField>
321
+
322
+ <FormField label="Due Date">
323
+ <DatePicker
324
+ value={newDeadline.date}
325
+ onChange={(date) => setNewDeadline(prev => ({ ...prev, date }))}
326
+ minDate={new Date()}
327
+ placeholder="Select due date..."
328
+ leadingIcon={<Icon icon="Today" />}
329
+ />
330
+ </FormField>
331
+
332
+ <Button onClick={addDeadline}>Add Deadline</Button>
333
+ </div>
334
+
335
+ <div className="deadlines-list">
336
+ <Text type="Heading5">Upcoming Deadlines</Text>
337
+
338
+ {deadlines.map(deadline => {
339
+ const daysUntil = getDaysUntil(deadline.date);
340
+ const isOverdue = daysUntil < 0;
341
+ const isUrgent = daysUntil <= 3 && daysUntil >= 0;
342
+
343
+ return (
344
+ <Card
345
+ key={deadline.id}
346
+ className={`deadline-card ${isOverdue ? 'overdue' : isUrgent ? 'urgent' : ''}`}
347
+ >
348
+ <Text type="Heading6">{deadline.title}</Text>
349
+ <Text type="BodySmall">
350
+ Due: {new Date(deadline.date).toLocaleDateString()}
351
+ </Text>
352
+ <Text type="BodySmall" className="days-until">
353
+ {isOverdue
354
+ ? `${Math.abs(daysUntil)} days overdue`
355
+ : daysUntil === 0
356
+ ? 'Due today!'
357
+ : `${daysUntil} days remaining`
358
+ }
359
+ </Text>
360
+ </Card>
361
+ );
362
+ })}
363
+ </div>
364
+ </div>
365
+ );
366
+ }
367
+ ```
368
+
369
+ ### Birthday Reminder
370
+ ```tsx
371
+ function BirthdayReminderExample() {
372
+ const [birthdate, setBirthdate] = useState(null);
373
+ const [name, setName] = useState('');
374
+
375
+ const calculateAge = (birthdate) => {
376
+ if (!birthdate) return null;
377
+ const today = new Date();
378
+ const birth = new Date(birthdate);
379
+ let age = today.getFullYear() - birth.getFullYear();
380
+ const monthDiff = today.getMonth() - birth.getMonth();
381
+
382
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
383
+ age--;
384
+ }
385
+
386
+ return age;
387
+ };
388
+
389
+ const getNextBirthday = (birthdate) => {
390
+ if (!birthdate) return null;
391
+ const today = new Date();
392
+ const birth = new Date(birthdate);
393
+ const thisYear = today.getFullYear();
394
+ let nextBirthday = new Date(thisYear, birth.getMonth(), birth.getDate());
395
+
396
+ if (nextBirthday < today) {
397
+ nextBirthday.setFullYear(thisYear + 1);
398
+ }
399
+
400
+ return nextBirthday;
401
+ };
402
+
403
+ const maxDate = new Date();
404
+ const minDate = new Date();
405
+ minDate.setFullYear(maxDate.getFullYear() - 120);
406
+
407
+ return (
408
+ <div className="birthday-form">
409
+ <Text type="Heading4">Birthday Reminder</Text>
410
+
411
+ <FormField label="Name" required>
412
+ <Input
413
+ value={name}
414
+ onChange={(e) => setName(e.target.value)}
415
+ placeholder="Enter name..."
416
+ />
417
+ </FormField>
418
+
419
+ <FormField label="Date of Birth" required>
420
+ <DatePicker
421
+ value={birthdate}
422
+ onChange={setBirthdate}
423
+ maxDate={maxDate}
424
+ minDate={minDate}
425
+ placeholder="Select birthdate..."
426
+ leadingIcon={<Icon icon="Cake" />}
427
+ dateFormat="F j, Y"
428
+ />
429
+ </FormField>
430
+
431
+ {name && birthdate && (
432
+ <Card className="birthday-info">
433
+ <Text type="Heading6">{name}'s Birthday Info</Text>
434
+ <div className="info-grid">
435
+ <div>
436
+ <Text type="BodySmall">Age:</Text>
437
+ <Text>{calculateAge(birthdate)} years old</Text>
438
+ </div>
439
+ <div>
440
+ <Text type="BodySmall">Next Birthday:</Text>
441
+ <Text>{getNextBirthday(birthdate)?.toLocaleDateString()}</Text>
442
+ </div>
443
+ <div>
444
+ <Text type="BodySmall">Days Until:</Text>
445
+ <Text>
446
+ {Math.ceil((getNextBirthday(birthdate) - new Date()) / (1000 * 60 * 60 * 24))} days
447
+ </Text>
448
+ </div>
449
+ </div>
450
+ </Card>
451
+ )}
452
+ </div>
453
+ );
454
+ }
455
+ ```
456
+
457
+ ### Custom Date Format Picker
458
+ ```tsx
459
+ function CustomFormatExample() {
460
+ const [date, setDate] = useState(null);
461
+ const [format, setFormat] = useState('Y-m-d');
462
+
463
+ const formats = [
464
+ { value: 'Y-m-d', label: 'YYYY-MM-DD', example: '2024-02-15' },
465
+ { value: 'F j, Y', label: 'Month Day, Year', example: 'February 15, 2024' },
466
+ { value: 'd/m/Y', label: 'DD/MM/YYYY', example: '15/02/2024' },
467
+ { value: 'm/d/Y', label: 'MM/DD/YYYY', example: '02/15/2024' },
468
+ { value: 'l, F j, Y', label: 'Full Date', example: 'Thursday, February 15, 2024' }
469
+ ];
470
+
471
+ const customParseDate = (dateStr, format) => {
472
+ // Custom parsing logic based on format
473
+ return new Date(dateStr);
474
+ };
475
+
476
+ return (
477
+ <div className="custom-format-picker">
478
+ <Text type="Heading5">Custom Date Format</Text>
479
+
480
+ <FormField label="Date Format">
481
+ <Select value={format} onChange={setFormat}>
482
+ {formats.map(fmt => (
483
+ <Option key={fmt.value} value={fmt.value}>
484
+ <div className="format-option">
485
+ <Text>{fmt.label}</Text>
486
+ <Text type="BodySmall" className="format-example">
487
+ {fmt.example}
488
+ </Text>
489
+ </div>
490
+ </Option>
491
+ ))}
492
+ </Select>
493
+ </FormField>
494
+
495
+ <FormField label="Select Date">
496
+ <DatePicker
497
+ value={date}
498
+ onChange={setDate}
499
+ dateFormat={format}
500
+ parseDate={customParseDate}
501
+ placeholder={`Enter date in ${format} format...`}
502
+ allowInput={true}
503
+ leadingIcon={<Icon icon="DateRange" />}
504
+ />
505
+ </FormField>
506
+
507
+ {date && (
508
+ <div className="date-preview">
509
+ <Text type="BodySmall">Selected Date:</Text>
510
+ <Text>{new Date(date).toLocaleDateString()}</Text>
511
+ </div>
512
+ )}
513
+ </div>
514
+ );
515
+ }
516
+ ```