{"version":3,"sources":["../../src/use-countdown/index.ts"],"sourcesContent":["import { normalizeDate } from '../use-date-format'\nimport { useIntervalFn } from '../use-interval-fn'\nimport { useLatest } from '../use-latest'\nimport { useSafeState } from '../use-safe-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { useUpdateEffect } from '../use-update-effect'\nimport { noNullish, now } from '../utils/basic'\nimport { unwrapGettable } from '../utils/unwrap'\n\nimport type { DateLike } from '../use-date-format'\nimport type { UseIntervalFnInterval } from '../use-interval-fn'\nimport type { Pausable } from '../use-pausable'\nimport type { Gettable } from '../utils/basic'\n\nexport interface UseCountdownDateItem {\n  d: number\n  h: number\n  m: number\n  s: number\n  ms: number\n}\n\nexport interface UseCountdownOptions<Controls extends boolean = false> {\n  /**\n   * whether to start the countdown immediately\n   *\n   * @defaultValue true\n   */\n  immediate?: boolean\n  /**\n   * whether to expose the controls\n   *\n   * @defaultValue false\n   */\n  controls?: Controls\n  /**\n   * the interval to update the countdown\n   *\n   * @defaultValue 'requestAnimationFrame'\n   */\n  interval?: UseIntervalFnInterval\n  /**\n   * a callback function to be called when the countdown is updated\n   */\n  onUpdate?: (ms: number, seconds: number) => void\n  /**\n   * a callback function to be called when the countdown is stopped\n   */\n  onStop?(): void\n}\n\nexport type UseCountdownReturns<Controls extends boolean> = Controls extends true\n  ? { ms: number; isStop: boolean } & Pausable\n  : number\n\nfunction calRemainingTime(date: Gettable<DateLike | null | undefined>) {\n  const dateValue = unwrapGettable(date)\n\n  if (noNullish(dateValue)) {\n    return Math.max(0, normalizeDate(dateValue).getTime() - now())\n  }\n\n  return 0\n}\n\n/**\n * A React Hook that provides a countdown timer.\n */\nexport function useCountdown(date: Gettable<DateLike | null | undefined>): UseCountdownReturns<false>\nexport function useCountdown(\n  date: Gettable<DateLike | null | undefined>,\n  options: UseCountdownOptions<false>,\n): UseCountdownReturns<false>\nexport function useCountdown(\n  date: Gettable<DateLike | null | undefined>,\n  options: UseCountdownOptions<true>,\n): UseCountdownReturns<true>\nexport function useCountdown(\n  date: Gettable<DateLike | null | undefined>,\n  options: UseCountdownOptions<boolean> = {},\n): UseCountdownReturns<boolean> {\n  const {\n    immediate = true,\n    controls: exposeControls = false,\n    interval = 'requestAnimationFrame',\n    onStop,\n    onUpdate,\n  } = options\n\n  const [ms, setMs] = useSafeState(() => calRemainingTime(date))\n\n  const update = useStableFn(() => {\n    const { date, onUpdate, onStop } = latest.current\n    const ms = calRemainingTime(date)\n\n    onUpdate?.(ms, Math.ceil(ms / 1000))\n\n    if (ms === 0) {\n      onStop?.()\n      controls.pause()\n    }\n\n    setMs(ms)\n  })\n\n  const controls = useIntervalFn(update, interval, { immediate })\n  const latest = useLatest({ ms, date, onStop, onUpdate })\n\n  useUpdateEffect(() => {\n    const ms = calRemainingTime(date)\n    setMs(ms)\n    ms > 0 ? controls.resume() : controls.pause()\n  }, [date])\n\n  return exposeControls ? { ms, isStop: ms === 0, ...controls } : ms\n}\n"],"names":["useCountdown","calRemainingTime","date","dateValue","unwrapGettable","noNullish","Math","max","normalizeDate","getTime","now","options","immediate","exposeControls","controls","interval","onStop","onUpdate","useSafeState","ms","setMs","update","useStableFn","latest","current","ceil","pause","useIntervalFn","useLatest","useUpdateEffect","resume","isStop"],"mappings":";;;;+BA6EgBA;;;eAAAA;;;6BA7Ec;6BACA;yBACJ;4BACG;2BACD;+BACI;qBACD;sBACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgD/B,SAASC,iBAAiBC,IAA2C;IACnE,IAAMC,YAAYC,IAAAA,sBAAc,EAACF;IAEjC,IAAIG,IAAAA,gBAAS,EAACF,YAAY;QACxB,OAAOG,KAAKC,GAAG,CAAC,GAAGC,IAAAA,4BAAa,EAACL,WAAWM,OAAO,KAAKC,IAAAA,UAAG;IAC7D;IAEA,OAAO;AACT;AAcO,SAASV,aACdE,IAA2C;QAC3CS,UAAAA,iEAAwC,CAAC;IAEzC,yBAMIA,QALFC,WAAAA,4CAAY,2BACFC,MAIRF,QAJFG,UAAUD,iBAAAA,iBAAiB,QAAjBA,yBAIRF,QAHFI,UAAAA,0CAAW,6CACXC,SAEEL,QAFFK,QACAC,WACEN,QADFM;IAGF,IAAoBC,iCAAAA,IAAAA,0BAAY,EAAC;eAAMjB,iBAAiBC;YAAjDiB,KAAaD,kBAATE,QAASF;IAEpB,IAAMG,SAASC,IAAAA,wBAAW,EAAC;QACzB,IAAmCC,kBAAAA,OAAOC,OAAO,EAAzCtB,SAA2BqB,gBAA3BrB,MAAMe,WAAqBM,gBAArBN,UAAUD,SAAWO,gBAAXP;QACxB,IAAMG,KAAKlB,iBAAiBC;QAE5Be,qBAAAA,+BAAAA,SAAWE,IAAIb,KAAKmB,IAAI,CAACN,KAAK;QAE9B,IAAIA,OAAO,GAAG;YACZH,mBAAAA,6BAAAA;YACAF,SAASY,KAAK;QAChB;QAEAN,MAAMD;IACR;IAEA,IAAML,WAAWa,IAAAA,4BAAa,EAACN,QAAQN,UAAU;QAAEH,WAAAA;IAAU;IAC7D,IAAMW,SAASK,IAAAA,oBAAS,EAAC;QAAET,IAAAA;QAAIjB,MAAAA;QAAMc,QAAAA;QAAQC,UAAAA;IAAS;IAEtDY,IAAAA,gCAAe,EAAC;QACd,IAAMV,KAAKlB,iBAAiBC;QAC5BkB,MAAMD;QACNA,KAAK,IAAIL,SAASgB,MAAM,KAAKhB,SAASY,KAAK;IAC7C,GAAG;QAACxB;KAAK;IAET,OAAOW,iBAAiB;QAAEM,IAAAA;QAAIY,QAAQZ,OAAO;OAAML,YAAaK;AAClE"}