11// Copyright (c) Cosmo Tech.
22// Licensed under the MIT license.
3- import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
3+ import React , { useCallback } from 'react' ;
44import PropTypes from 'prop-types' ;
5- import { Stack , TextField } from '@mui/material' ;
5+ import { Stack } from '@mui/material' ;
66import makeStyles from '@mui/styles/makeStyles' ;
7- import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns ' ;
7+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs ' ;
88import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker' ;
99import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider' ;
10- import { DateUtils } from '@cosmotech/core' ;
10+ import dayjs from 'dayjs' ;
11+ import timezone from 'dayjs/plugin/timezone' ;
12+ import utc from 'dayjs/plugin/utc' ;
1113import { TooltipInfo } from '../../../misc' ;
1214import { getCommonInputStyles } from '../../style' ;
1315import { BasicInputPlaceholder } from '../BasicInputPlaceholder' ;
1416
1517const useStyles = makeStyles ( getCommonInputStyles ) ;
18+ dayjs . extend ( utc ) ;
19+ dayjs . extend ( timezone ) ;
1620
17- const _computeInternalDate = ( value , reverseTimezoneOffset ) => {
18- if ( value == null ) return value ;
19- return reverseTimezoneOffset ? DateUtils . addLocalDateToUTCOffset ( value ) : value ;
20- } ;
21-
22- const _getInternalDateToReturnToParent = ( value , reverseTimezoneOffset ) => {
23- if ( value == null ) return value ;
24- return reverseTimezoneOffset ? DateUtils . addUTCToLocalDateOffset ( value ) : value ;
25- } ;
21+ const TIME_ZONE = 'UTC' ;
2622
2723export const BasicDateInput = ( props ) => {
2824 const {
@@ -41,30 +37,11 @@ export const BasicDateInput = (props) => {
4137 } = props ;
4238 const classes = useStyles ( ) ;
4339
44- // DesktopDatePicker always work in users' local time, meaning that dates provided as UTC may be displayed as a
45- // different day based on users' timezeone offset. For uses cases that only need tha "date" part withtout "time", we
46- // should ignore timezones and must thus add an internal state to reverse the timezone offset (this behavior is
47- // enabled only if reverseTimezoneOffset is set to true)
48- const [ internalDate , setInternalDate ] = useState ( _computeInternalDate ( value , reverseTimezoneOffset ) ) ;
49- const minDate = useMemo (
50- ( ) => _computeInternalDate ( dateProps . minDate , reverseTimezoneOffset ) ,
51- [ dateProps , reverseTimezoneOffset ]
52- ) ;
53- const maxDate = useMemo (
54- ( ) => _computeInternalDate ( dateProps . maxDate , reverseTimezoneOffset ) ,
55- [ dateProps , reverseTimezoneOffset ]
56- ) ;
57-
58- useEffect ( ( ) => {
59- setInternalDate ( _computeInternalDate ( value , reverseTimezoneOffset ) ) ;
60- } , [ reverseTimezoneOffset , value ] ) ;
61-
6240 const onChange = useCallback (
6341 ( newValue ) => {
64- setInternalDate ( newValue ) ;
65- changeSelectedDate ( _getInternalDateToReturnToParent ( newValue , reverseTimezoneOffset ) ) ;
42+ changeSelectedDate ( newValue == null ? newValue : new Date ( newValue ?. format ( ) ) ) ;
6643 } ,
67- [ reverseTimezoneOffset , changeSelectedDate ]
44+ [ changeSelectedDate ]
6845 ) ;
6946
7047 if ( dateProps . disabled )
@@ -73,7 +50,7 @@ export const BasicDateInput = (props) => {
7350 id = { `date-input-${ id } ` }
7451 label = { label }
7552 tooltipText = { tooltipText }
76- value = { internalDate ?. toLocaleDateString ( ) ?? '' }
53+ value = { value ?. toLocaleDateString ( 'en-US' , { timeZone : TIME_ZONE } ) ?? '' }
7754 { ...otherProps }
7855 />
7956 ) ;
@@ -86,26 +63,26 @@ export const BasicDateInput = (props) => {
8663 className = { isDirty ? classes . dirtyInput : isDirty === false ? classes . notDirtyInput : '' }
8764 sx = { { alignItems : 'center' } }
8865 >
89- < LocalizationProvider dateAdapter = { AdapterDateFns } >
66+ < LocalizationProvider dateAdapter = { AdapterDayjs } >
9067 < DesktopDatePicker
9168 label = { label }
9269 inputFormat = { format }
93- minDate = { minDate }
94- maxDate = { maxDate }
95- renderInput = { ( { error : _ , ... params } ) => (
96- < TextField
97- id = { `date-text-field- ${ id } ` }
98- variant = "outlined"
99- sx = { { flexGrow : 1 } }
100- size = { size }
101- error = { error ?. message ?. length > 0 }
102- helperText = { error ?. message ?? '' }
103- { ... params }
104- />
105- ) }
70+ minDate = { dateProps . minDate ? dayjs ( dateProps . minDate ) : null }
71+ maxDate = { dateProps . minDate ? dayjs ( dateProps . maxDate ) : null }
72+ timezone = { TIME_ZONE }
73+ slotProps = { {
74+ textField : {
75+ id : `date-text-field- ${ id } ` ,
76+ variant : 'outlined' ,
77+ sx : { flexGrow : 1 } ,
78+ error : error ?. message ?. length > 0 ,
79+ helperText : error ?. message ?? '' ,
80+ size ,
81+ } ,
82+ } }
10683 id = { `date-input-${ id } ` }
10784 onChange = { onChange }
108- value = { internalDate ?? new Date ( undefined ) }
85+ value = { dayjs ( value ) }
10986 />
11087 </ LocalizationProvider >
11188 < TooltipInfo title = { tooltipText } variant = "small" />
0 commit comments