77 DatePickerSingleExample ,
88 DatePickerRangeExample ,
99 DatePickerRangeWithPresetsExample ,
10+ DatePickerErrorExample ,
11+ DatePickerDisabledExample ,
12+ DatePickerWithValidationExample ,
1013} from " ../../../src/components/date-picker-examples" ;
1114
1215### Usage
@@ -122,6 +125,9 @@ export function UnifiedExample() {
122125- ` disabled ` - Disabled dates (can be a function, date, or array) (optional)
123126- ` className ` - Custom className for the trigger button (optional)
124127- ` align ` - Align popover content: ` "start" ` , ` "center" ` , or ` "end" ` (default: ` "start" ` )
128+ - ` isErrored ` - Whether the date picker is in an error state (optional, default: ` false ` )
129+ - ` disabledBtn ` - Whether the trigger button is disabled (optional, default: ` false ` )
130+ - ` dateFormat ` - Date format string for displaying dates using date-fns format tokens (optional)
125131
126132#### Single Date Mode Props
127133
@@ -316,25 +322,161 @@ const disabledDates = [
316322/>
317323```
318324
325+ ### Error State
326+
327+ Use the ` isErrored ` prop to indicate validation errors:
328+
329+ ``` tsx
330+ import { DatePickerSingle } from " @prisma-docs/eclipse" ;
331+ import { useState } from " react" ;
332+
333+ export function FormWithValidation() {
334+ const [date, setDate] = useState <Date >();
335+ const [submitted, setSubmitted] = useState (false );
336+
337+ const hasError = submitted && ! date ;
338+
339+ return (
340+ <div className = " space-y-2" >
341+ <DatePickerSingle
342+ date = { date }
343+ onDateChange = { setDate }
344+ placeholder = " Select a date"
345+ isErrored = { hasError }
346+ />
347+ { hasError && (
348+ <p className = " text-sm text-foreground-error" >
349+ Date is required
350+ </p >
351+ )}
352+ </div >
353+ );
354+ }
355+ ```
356+
357+ ** Live Example (Static Error State):**
358+
359+ <div className = " my-4 max-w-md" >
360+ <DatePickerErrorExample />
361+ </div >
362+
363+ ** Live Example (With Validation):**
364+
365+ <div className = " my-4 max-w-md" >
366+ <DatePickerWithValidationExample />
367+ </div >
368+
369+ The error state adds a red ring (` ring-2 ring-stroke-error ` ) to the button and changes the text and icon color to ` text-foreground-error ` to indicate the validation error.
370+
371+ ### Disabled State
372+
373+ Use the ` disabledBtn ` prop to disable the entire date picker button:
374+
375+ ``` tsx
376+ <DatePickerSingle
377+ date = { date }
378+ onDateChange = { setDate }
379+ placeholder = " Disabled picker"
380+ disabledBtn = { true }
381+ />
382+ ```
383+
384+ ** Live Example:**
385+
386+ <div className = " my-4 max-w-md" >
387+ <DatePickerDisabledExample />
388+ </div >
389+
390+ ** Use Cases:**
391+ - Disable based on permissions
392+ - Disable while data is loading
393+ - Disable when form is submitting
394+ - Conditional disabling based on other form fields
395+
396+ ``` tsx
397+ function ConditionalDatePicker() {
398+ const [isSubscribed, setIsSubscribed] = useState (false );
399+ const [date, setDate] = useState <Date >();
400+
401+ return (
402+ <div className = " space-y-4" >
403+ <label >
404+ <input
405+ type = " checkbox"
406+ checked = { isSubscribed }
407+ onChange = { (e ) => setIsSubscribed (e .target .checked )}
408+ />
409+ Enable premium features
410+ </label >
411+
412+ <DatePickerSingle
413+ date = { date }
414+ onDateChange = { setDate }
415+ placeholder = " Premium feature - select date"
416+ disabledBtn = { ! isSubscribed }
417+ />
418+ </div >
419+ );
420+ }
421+ ```
422+
319423### Formatting
320424
321- The component uses ` date-fns ` for date formatting:
425+ The component uses ` date-fns ` for date formatting. You can customize the format using the ` dateFormat ` prop :
322426
427+ ** Default Formats:**
323428- ** Single date** : ` PPP ` format (e.g., "April 29, 2024")
324429- ** Date range** : ` LLL dd, y ` format (e.g., "Apr 01, 2024 - Apr 30, 2024")
325430
326- To customize formatting, you can format the dates in your component:
431+ ** Custom Formats: **
327432
328433``` tsx
329- import { format } from " date-fns" ;
434+ // European format: dd/MM/yyyy
435+ <DatePickerSingle
436+ date = { date }
437+ onDateChange = { setDate }
438+ dateFormat = " dd/MM/yyyy"
439+ placeholder = " Select date"
440+ />
441+ // Output: "17/02/2026"
442+
443+ // US format: MM/dd/yyyy
444+ <DatePickerSingle
445+ date = { date }
446+ onDateChange = { setDate }
447+ dateFormat = " MM/dd/yyyy"
448+ />
449+ // Output: "02/17/2026"
330450
451+ // ISO format: yyyy-MM-dd
331452<DatePickerSingle
332453 date = { date }
333454 onDateChange = { setDate }
334- placeholder = { date ? format (date , " MM/dd/yyyy" ) : " Select date" }
455+ dateFormat = " yyyy-MM-dd"
456+ />
457+ // Output: "2026-02-17"
458+
459+ // Custom verbose format
460+ <DatePickerRange
461+ dateRange = { dateRange }
462+ onDateRangeChange = { setDateRange }
463+ dateFormat = " EEEE, MMMM do, yyyy"
335464/>
465+ // Output: "Tuesday, February 17th, 2026 - Friday, February 20th, 2026"
336466```
337467
468+ ** Common date-fns Format Tokens:**
469+ - ` dd ` - Day of month (01-31)
470+ - ` MM ` - Month (01-12)
471+ - ` yyyy ` - Full year (2026)
472+ - ` yy ` - 2-digit year (26)
473+ - ` MMM ` - Short month name (Feb)
474+ - ` MMMM ` - Full month name (February)
475+ - ` do ` - Day with ordinal (17th)
476+ - ` EEEE ` - Full day name (Tuesday)
477+ - ` PPP ` - Long localized date (February 17th, 2026)
478+ - ` P ` - Short localized date (02/17/2026)
479+
338480### Best Practices
339481
340482- Use ** single date picker** for events, deadlines, or appointments
@@ -346,6 +488,9 @@ import { format } from "date-fns";
346488- Add ** validation** to ensure date ranges make sense
347489- Show ** clear labels** above date pickers in forms
348490- Use ** consistent date formats** across your application
491+ - Use ` isErrored ` prop with validation messages for better UX
492+ - Use ` disabledBtn ` for conditional access or loading states
493+ - Choose appropriate ` dateFormat ` based on your user's locale and preferences
349494
350495### Accessibility
351496
@@ -397,19 +542,28 @@ import { useForm, Controller } from "react-hook-form";
397542import { DatePickerSingle } from " @prisma-docs/eclipse" ;
398543
399544function MyForm() {
400- const { control, handleSubmit } = useForm ();
545+ const { control, handleSubmit, formState : { errors } } = useForm ();
401546
402547 return (
403548 <form onSubmit = { handleSubmit (onSubmit )} >
404549 <Controller
405550 control = { control }
406551 name = " eventDate"
552+ rules = { { required: " Event date is required" }}
407553 render = { ({ field }) => (
408- <DatePickerSingle
409- date = { field .value }
410- onDateChange = { field .onChange }
411- placeholder = " Select event date"
412- />
554+ <div className = " space-y-2" >
555+ <DatePickerSingle
556+ date = { field .value }
557+ onDateChange = { field .onChange }
558+ placeholder = " Select event date"
559+ isErrored = { !! errors .eventDate }
560+ />
561+ { errors .eventDate && (
562+ <p className = " text-sm text-foreground-error" >
563+ { errors .eventDate .message }
564+ </p >
565+ )}
566+ </div >
413567 )}
414568 />
415569 </form >
0 commit comments