@@ -7,12 +7,20 @@ import React, {
77 useImperativeHandle ,
88} from 'react'
99import { View } from '@tarojs/components'
10- import { useConfig } from '@/packages/configprovider/configprovider.taro'
1110import { BasicComponent , ComponentDefaults } from '@/utils/typings'
1211import { padZero } from '@/utils/pad-zero'
13- import { harmonyAndRn } from '@/utils/platform-taro'
12+ import { harmonyAndRn , web } from '@/utils/platform-taro'
1413
14+ export interface CountDownTimeProps {
15+ d : number
16+ h : number
17+ m : number
18+ s : number
19+ ms : number
20+ }
21+ export type CountDownType = 'default' | 'primary'
1522export interface CountDownProps extends BasicComponent {
23+ type : CountDownType
1624 paused : boolean
1725 startTime : number
1826 endTime : number
@@ -31,6 +39,7 @@ export interface CountDownProps extends BasicComponent {
3139
3240const defaultProps = {
3341 ...ComponentDefaults ,
42+ type : 'default' ,
3443 paused : false ,
3544 startTime : Date . now ( ) ,
3645 endTime : Date . now ( ) ,
@@ -46,8 +55,8 @@ const InternalCountDown: ForwardRefRenderFunction<
4655 unknown ,
4756 Partial < CountDownProps >
4857> = ( props , ref ) => {
49- const { locale } = useConfig ( )
5058 const {
59+ type,
5160 paused,
5261 startTime,
5362 endTime,
@@ -94,7 +103,7 @@ const InternalCountDown: ForwardRefRenderFunction<
94103 stateRef . current . handleEndTime = Date . now ( ) + Number ( remainingTime )
95104 } else {
96105 stateRef . current . handleEndTime = endTime
97- if ( ! harmonyAndRn ( ) ) {
106+ if ( web ( ) ) {
98107 stateRef . current . diffTime = Date . now ( ) - getTimeStamp ( startTime ) // 时间差
99108 }
100109 }
@@ -127,7 +136,7 @@ const InternalCountDown: ForwardRefRenderFunction<
127136 } )
128137 }
129138
130- // 将倒计时剩余时间格式化 参数: t 时间戳 type custom 自定义类型
139+ // 将倒计时剩余时间格式化 参数:t时间戳 type custom 自定义类型
131140 const formatRemainTime = ( t : number , type ?: string ) => {
132141 const ts = t
133142 const rest = {
@@ -152,13 +161,7 @@ const InternalCountDown: ForwardRefRenderFunction<
152161 return type === 'custom' ? rest : parseFormat ( { ...rest } )
153162 }
154163
155- const parseFormat = ( time : {
156- d : number
157- h : number
158- m : number
159- s : number
160- ms : number
161- } ) => {
164+ const parseFormat = ( time : CountDownTimeProps ) => {
162165 const { d } = time
163166 let { h, m, s, ms } = time
164167 let formatCache = format
@@ -198,8 +201,16 @@ const InternalCountDown: ForwardRefRenderFunction<
198201 formatCache = formatCache . replace ( 'SS' , msC . slice ( 0 , 1 ) )
199202 }
200203 }
204+ formatCache = formatCache . replace (
205+ / ( \d + ) / g,
206+ type === 'primary'
207+ ? `<View class="nut-countdown-number-primary">$1</View>`
208+ : `<View class="nut-countdown-number">$1</View>`
209+ )
210+
201211 return formatCache
202212 }
213+
203214 // 暂定
204215 const pause = ( ) => {
205216 cancelAnimationFrame ( stateRef . current . timer )
@@ -286,25 +297,87 @@ const InternalCountDown: ForwardRefRenderFunction<
286297 return formatRemainTime ( stateRef . current . restTime )
287298 } ) ( )
288299
300+ const getUnit = ( unit : string ) => {
301+ const formatArr = format . split ( / ( D D | H H | m m | s s | S ) / )
302+ const index = formatArr . indexOf ( unit )
303+ return index > - 1 ? formatArr [ index + 1 ] : ':'
304+ }
305+
306+ const renderTimeItem = (
307+ formatUnit : string ,
308+ time : number | string ,
309+ unit = ''
310+ ) => {
311+ return (
312+ < >
313+ { format . includes ( formatUnit ) ? (
314+ < >
315+ < View
316+ className = { `${ classPrefix } -number${ type === 'primary' ? '-primary' : '' } ` }
317+ >
318+ { padZero ( time ) }
319+ </ View >
320+ { unit ? (
321+ < View className = { `${ classPrefix } -unit` } > { getUnit ( unit ) } </ View >
322+ ) : null }
323+ </ >
324+ ) : null }
325+ </ >
326+ )
327+ }
328+
329+ const renderTaroTime = ( ) => {
330+ const formatCache = formatRemainTime ( stateRef . current . restTime , 'custom' )
331+ const { d, h, m, s, ms } = formatCache as CountDownTimeProps
332+ const digit = format . match ( / S / g) ?. length
333+ // format可能是DD天HH时mm分SSS秒或者DD天HH时mm分S秒或是DD:HH:mm:ss
334+
335+ return (
336+ < >
337+ { renderTimeItem ( 'DD' , d , 'DD' ) }
338+ { renderTimeItem ( 'HH' , h , 'HH' ) }
339+ { renderTimeItem ( 'mm' , m , 'mm' ) }
340+ { renderTimeItem ( 'ss' , s ) }
341+ { ( format . includes ( 'S' ) || getUnit ( 'ss' ) !== ':' ) && (
342+ < >
343+ < View className = { `${ classPrefix } -unit` } > { getUnit ( 'ss' ) } </ View >
344+ </ >
345+ ) }
346+ { renderTimeItem (
347+ 'S' ,
348+ padZero ( ms , 3 )
349+ . toString ( )
350+ . slice ( 0 , digit || 2 )
351+ ) }
352+ </ >
353+ )
354+ }
355+
289356 return (
290- < View
291- className = { `${ classPrefix } ${ className } ` }
292- style = { { ...style } }
293- { ...rest }
294- >
357+ < >
295358 { children || (
296- < View
297- className = { `${ classPrefix } -block` }
298- // eslint-disable-next-line react/no-danger
299- // TODO:RN和鸿蒙暂时不支持dangerouslySetInnerHTML
300- // dangerouslySetInnerHTML={{
301- // __html: `${renderTime}`,
302- // }}
303- >
304- { renderTime as any }
305- </ View >
359+ < >
360+ { ! harmonyAndRn ( ) ? (
361+ < View
362+ className = { `${ classPrefix } ${ className } ` }
363+ style = { { ...style } }
364+ { ...rest }
365+ dangerouslySetInnerHTML = { {
366+ __html : `${ renderTime } ` ,
367+ } }
368+ />
369+ ) : (
370+ < View
371+ className = { `${ classPrefix } ${ className } ` }
372+ style = { { ...style } }
373+ { ...rest }
374+ >
375+ { renderTaroTime ( ) }
376+ </ View >
377+ ) }
378+ </ >
306379 ) }
307- </ View >
380+ </ >
308381 )
309382}
310383
0 commit comments