@@ -4,6 +4,7 @@ import { DateRange, DayPicker, DayPickerProps, Locale, Matcher, OnSelectHandler
44import { UnknownType } from 'src/tedi/types/commonTypes' ;
55
66import { CalendarView , DateFieldMode } from '../date-field/date-field' ;
7+ import { TimePicker } from '../time-picker/time-picker' ;
78import { CalendarHeader } from './components/date-calendar-header/date-calendar-header' ;
89import { MonthGrid } from './components/date-calendar-month-grid/date-calendar-month-grid' ;
910import { YearGrid } from './components/date-calendar-year-grid/date-calendar-year-grid' ;
@@ -84,6 +85,27 @@ export interface DateCalendarProps extends Omit<DayPickerProps, 'mode' | 'select
8485 * Optional additional CSS class for the calendar container.
8586 */
8687 className ?: string ;
88+ /**
89+ * Show a time picker below the calendar for selecting hours and minutes.
90+ * @default false
91+ */
92+ showTimePicker ?: boolean ;
93+ /**
94+ * Optional initial time value as "HH:mm" string.
95+ */
96+ time ?: string ;
97+ /**
98+ * Callback fired when time changes.
99+ */
100+ onTimeChange ?: ( time : string ) => void ;
101+ /**
102+ * Slots for custom content in different areas of the calendar.
103+ */
104+ slots ?: {
105+ side ?: React . ReactNode ;
106+ footer ?: React . ReactNode ;
107+ header ?: React . ReactNode ;
108+ } ;
87109}
88110
89111export const DateCalendar = ( {
@@ -104,10 +126,20 @@ export const DateCalendar = ({
104126 handleSelect,
105127 applyValue,
106128 className,
129+ showTimePicker = false ,
130+ time,
131+ onTimeChange,
132+ slots,
107133 ...dayPickerProps
108134} : DateCalendarProps ) => {
109135 return (
110- < div className = { styles [ 'tedi-date-calendar' ] } >
136+ < div
137+ className = { classNames (
138+ styles [ 'tedi-date-calendar' ] ,
139+ showTimePicker && styles [ 'tedi-date-calendar--with-timepicker' ] ,
140+ className
141+ ) }
142+ >
111143 { ( view === 'years' || calendarView === 'years' ) && (
112144 < YearGrid
113145 currentMonth = { currentMonth }
@@ -139,56 +171,68 @@ export const DateCalendar = ({
139171 ) }
140172
141173 { view === 'days' && (
142- < DayPicker
143- { ...dayPickerProps }
144- mode = { mode }
145- selected = { value as UnknownType }
146- locale = { locale }
147- month = { currentMonth }
148- onMonthChange = { setCurrentMonth }
149- showOutsideDays = { showOutsideDays }
150- disabled = { disabledMatchers ?. length ? disabledMatchers : undefined }
151- required = { required }
152- components = { {
153- MonthCaption : ( props ) => (
154- < CalendarHeader
155- { ...props }
156- monthYearSelectGrid = { monthYearSelectGrid }
157- onOpenMonthGrid = { ( ) => setView ( 'months' ) }
158- onOpenYearGrid = { ( ) => setView ( 'years' ) }
159- />
160- ) ,
161- Nav : ( ) => < > </ > ,
162- } }
163- footer = { footer }
164- classNames = { {
165- root : classNames ( styles [ 'tedi-date-calendar' ] , className ) ,
166- month_caption : styles [ 'tedi-date-calendar__caption' ] ,
167- head : styles [ 'tedi-date-calendar__head' ] ,
168- row : styles [ 'tedi-date-calendar__row' ] ,
169- day : styles [ 'tedi-date-calendar__day' ] ,
170- selected : styles [ 'tedi-date-calendar__day--selected' ] ,
171- weekday : styles [ 'tedi-date-calendar__weekday' ] ,
172- outside : styles [ 'tedi-date-calendar__outside-days' ] ,
173- range_start : styles [ 'tedi-date-calendar__range-start' ] ,
174- range_middle : styles [ 'tedi-date-calendar__range-middle' ] ,
175- range_end : styles [ 'tedi-date-calendar__range-end' ] ,
176- today : styles [ 'tedi-date-calendar__today' ] ,
177- disabled : styles [ 'tedi-date-calendar__disabled' ] ,
178- month : styles [ 'tedi-date-calendar__month' ] ,
179- months : styles [ 'tedi-date-calendar__months-container' ] ,
180- footer : styles [ 'tedi-date-calendar__footer' ] ,
181- week_number : styles [ 'tedi-date-calendar__week-number' ] ,
182- } }
183- modifiers = { {
184- available :
185- availableDays instanceof Function
186- ? availableDays
187- : ( d ) => availableDays ?. some ( ( day ) => day . toDateString ( ) === d . toDateString ( ) ) ?? false ,
188- } }
189- modifiersClassNames = { { available : styles [ 'tedi-date-calendar__available-day' ] } }
190- onSelect = { handleSelect }
191- />
174+ < div className = { styles [ 'tedi-date-calendar__layout' ] } >
175+ < div className = { styles [ 'tedi-date-calendar__main' ] } >
176+ < DayPicker
177+ { ...dayPickerProps }
178+ mode = { mode }
179+ selected = { value as UnknownType }
180+ locale = { locale }
181+ month = { currentMonth }
182+ onMonthChange = { setCurrentMonth }
183+ showOutsideDays = { showOutsideDays }
184+ disabled = { disabledMatchers ?. length ? disabledMatchers : undefined }
185+ required = { required }
186+ components = { {
187+ MonthCaption : ( props ) => (
188+ < CalendarHeader
189+ { ...props }
190+ monthYearSelectGrid = { monthYearSelectGrid }
191+ onOpenMonthGrid = { ( ) => setView ( 'months' ) }
192+ onOpenYearGrid = { ( ) => setView ( 'years' ) }
193+ />
194+ ) ,
195+ Nav : ( ) => < > </ > ,
196+ } }
197+ footer = { slots ?. footer || footer }
198+ classNames = { {
199+ root : styles [ 'tedi-date-calendar' ] ,
200+ month_caption : styles [ 'tedi-date-calendar__caption' ] ,
201+ head : styles [ 'tedi-date-calendar__head' ] ,
202+ row : styles [ 'tedi-date-calendar__row' ] ,
203+ day : styles [ 'tedi-date-calendar__day' ] ,
204+ selected : styles [ 'tedi-date-calendar__day--selected' ] ,
205+ weekday : styles [ 'tedi-date-calendar__weekday' ] ,
206+ outside : styles [ 'tedi-date-calendar__outside-days' ] ,
207+ range_start : styles [ 'tedi-date-calendar__range-start' ] ,
208+ range_middle : styles [ 'tedi-date-calendar__range-middle' ] ,
209+ range_end : styles [ 'tedi-date-calendar__range-end' ] ,
210+ today : styles [ 'tedi-date-calendar__today' ] ,
211+ disabled : styles [ 'tedi-date-calendar__disabled' ] ,
212+ month : styles [ 'tedi-date-calendar__month' ] ,
213+ months : styles [ 'tedi-date-calendar__months-container' ] ,
214+ footer : styles [ 'tedi-date-calendar__footer' ] ,
215+ week_number : styles [ 'tedi-date-calendar__week-number' ] ,
216+ } }
217+ modifiers = { {
218+ available :
219+ availableDays instanceof Function
220+ ? availableDays
221+ : ( d ) => availableDays ?. some ( ( day ) => day . toDateString ( ) === d . toDateString ( ) ) ?? false ,
222+ } }
223+ modifiersClassNames = { { available : styles [ 'tedi-date-calendar__available-day' ] } }
224+ onSelect = { handleSelect }
225+ />
226+ </ div >
227+
228+ { slots ?. side && < div className = { styles [ 'tedi-date-calendar__side' ] } > { slots . side } </ div > }
229+
230+ { showTimePicker && (
231+ < div className = { styles [ 'tedi-date-calendar__timepicker' ] } >
232+ < TimePicker value = { time } onChange = { onTimeChange } stepMinutes = { 1 } />
233+ </ div >
234+ ) }
235+ </ div >
192236 ) }
193237 </ div >
194238 ) ;
0 commit comments