jsx import React , { useEffect , useState } from "react" ; import { Interpolation , jsx , Theme } from "@emotion/react" ; import { Countdown , CountdownOption , CountdownValue , CountdownValueIndex } from "../utils/Countdown" ; import { RowStart } from "../Flex/Row" ; export interface CountdownerOption extends CountdownOption , React . HTMLProps < HTMLDivElement > { seperator ? : React . ReactNode ; seperatorStyle ? : Interpolation < Theme > ; containerStyle ? : Interpolation < Theme > ; numberStyle ? : Interpolation < Theme > ; renderNumber ? : ( value : number , key ? : string ) => React . ReactNode ; renderSeperator ? : ( value : number , key ? : string ) => React . ReactNode ; } export function Countdowner ( props ) { let { remain = 0 , seperator = ":" , format = "his" , onUpdate , onEnd , seperatorStyle , containerStyle , numberStyle , renderNumber , renderSeperator , ... extra } = props ; const [ value , setValue ] = useState < CountdownValue | null > ( null ) ; let content = [ ] ; if ( value && typeof value === "object" ) { for ( let i = 0 ; i < format . length ; i ++ ) { const key = format [ i ] as CountdownValueIndex ; const num = value ! [ key ] ! ; let numberComponent ; if ( typeof renderNumber === "function" ) { numberComponent = renderNumber ( num , key ) ; } else { numberComponent = < span css = { numberStyle } > { num < 10 ? `0${ num }` : num } < /span>; } content . push ( < React . Fragment key = { i } > { numberComponent } < /React.Fragment>); if ( i !== format . length - 1 ) { let seperatorComponent ; if ( typeof renderSeperator === "function" ) { seperatorComponent = renderSeperator ( num , key ) ; } else { seperatorComponent = seperator ? < span css = { seperatorStyle } > { seperator } < /span> : null; } content . push ( < React . Fragment key = { `s${ i }` } > { seperatorComponent } < /React.Fragment>); } } } useEffect ( ( ) => { let instance = new Countdown ( { format , remain , onUpdate ( current ) { setValue ( current ) ; onUpdate ?. ( current ) ; } , onEnd ( ) { onEnd ?. ( ) ; } , } ) ; instance . start ( ) ; return ( ) => { instance ! . stop ( ) ; instance = null ; } ; } , [ format , remain ] ) ; return ( < RowStart { ... extra } css = { containerStyle } > { content } < /RowStart>); }