1- import React from 'react' ;
1+ import React , { useState , useEffect , useRef } from 'react' ;
22import PropTypes from 'prop-types' ;
33import { useFieldApi } from '@data-driven-forms/react-form-renderer' ;
44
@@ -9,19 +9,79 @@ import prepareProps from '../common/prepare-props';
99const TimePicker = ( props ) => {
1010 const { input, meta, twelveHoursFormat, timezones, validateOnMount, ...rest } = useFieldApi ( prepareProps ( props ) ) ;
1111
12+ const [ timezone , selectTimezone ] = useState ( timezones ? timezones [ 0 ] ?. value : '' ) ;
13+ const [ format , selectFormat ] = useState ( 'AM' ) ;
14+ const isMounted = useRef ( false ) ;
15+
1216 const invalid = ( meta . touched || validateOnMount ) && meta . error ;
1317
18+ let finalValue = input . value ;
19+ if ( input . value instanceof Date ) {
20+ let [ hours = '00' , minutes = '00' ] = input . value
21+ . toLocaleTimeString ( 'en-us' , {
22+ hour12 : ! ! twelveHoursFormat ,
23+ timeZone : timezones . find ( ( { value } ) => value === timezone ) ?. showAs
24+ } )
25+ . split ( ':' ) ;
26+
27+ finalValue = `${ String ( hours ) . padStart ( 2 , '0' ) } :${ String ( minutes ) . padStart ( 2 , '0' ) } ` ;
28+ }
29+
30+ const enhnancedOnBlur = ( ) => {
31+ let [ hours = '00' , minutes = '00' ] = finalValue ?. split ( ':' ) || [ ] ;
32+
33+ if ( ! hours || isNaN ( hours ) ) {
34+ hours = '00' ;
35+ }
36+
37+ if ( ! minutes || isNaN ( minutes ) ) {
38+ minutes = '00' ;
39+ }
40+
41+ if ( twelveHoursFormat ) {
42+ hours = hours % 12 ;
43+ if ( format === 'PM' ) {
44+ hours = hours + 12 ;
45+ }
46+ } else {
47+ hours = hours % 24 ;
48+ }
49+
50+ minutes = minutes % 59 ;
51+ const enhancedValue = new Date ( `Jan 1 2000 ${ hours } :${ minutes } :00 ${ timezone } ` ) ;
52+
53+ input . onChange ( enhancedValue ) ;
54+ input . onBlur ( ) ;
55+ } ;
56+
57+ useEffect ( ( ) => {
58+ if ( isMounted . current === true ) {
59+ enhnancedOnBlur ( ) ;
60+ } else {
61+ isMounted . current = true ;
62+ }
63+ } , [ timezone , format ] ) ;
64+
1465 return (
15- < CarbonTimePicker { ...input } key = { input . name } id = { input . name } invalid = { Boolean ( invalid ) } invalidText = { invalid || '' } { ...rest } >
66+ < CarbonTimePicker
67+ { ...input }
68+ value = { finalValue }
69+ onBlur = { enhnancedOnBlur }
70+ key = { input . name }
71+ id = { input . name }
72+ invalid = { Boolean ( invalid ) }
73+ invalidText = { invalid || '' }
74+ { ...rest }
75+ >
1676 { twelveHoursFormat && (
17- < TimePickerSelect id = { `${ rest . id || input . name } -12h` } >
77+ < TimePickerSelect labelText = "Period" id = { `${ rest . id || input . name } -12h` } onChange = { ( { target : { value } } ) => selectFormat ( value ) } >
1878 < SelectItem value = "AM" text = "AM" />
1979 < SelectItem value = "PM" text = "PM" />
2080 </ TimePickerSelect >
2181 ) }
2282 { timezones && (
23- < TimePickerSelect id = { `${ rest . id || input . name } -timezones` } >
24- { timezones . map ( ( tz ) => (
83+ < TimePickerSelect labelText = "Timezone" id = { `${ rest . id || input . name } -timezones` } onChange = { ( { target : { value } } ) => selectTimezone ( value ) } >
84+ { timezones . map ( ( { showAs , ... tz } ) => (
2585 < SelectItem key = { tz . value } text = { tz . label } { ...tz } />
2686 ) ) }
2787 </ TimePickerSelect >
@@ -40,8 +100,9 @@ TimePicker.propTypes = {
40100 twelveHoursFormat : PropTypes . bool ,
41101 timezones : PropTypes . arrayOf (
42102 PropTypes . shape ( {
43- value : PropTypes . string ,
44- label : PropTypes . node
103+ value : PropTypes . string . isRequired ,
104+ label : PropTypes . node . isRequired ,
105+ showAs : PropTypes . string . isRequired
45106 } )
46107 )
47108} ;
0 commit comments