mimir-ui-kit 1.8.1 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ ._timer_llwad_3{color:var(--black-60);font-size:var(--size-text-l)}@media (max-width: 600px){._timer_llwad_3{font-size:var(--size-text-m)}}
@@ -0,0 +1,24 @@
1
+ type TProps = {
2
+ /**
3
+ * число, которое представляет собой временную метку, указывающую время, когда истекает таймер.
4
+ * const timer = new Date().getTime() + 60000; => таймер на 1 минуту
5
+ */
6
+ expiryTimestamp: number;
7
+ /**
8
+ * необязательное свойство типа boolean, которое указывает, должен ли таймер начинаться автоматически при создании компонента.
9
+ */
10
+ autoStart?: boolean;
11
+ /**
12
+ * необязательная функция, которая вызывается, когда таймер истекает.
13
+ */
14
+ onTimerEnd?: () => void;
15
+ /**
16
+ * Дополнительный класс.
17
+ */
18
+ className?: string;
19
+ };
20
+ /**
21
+ * Компонент Timer отображает таймер с отсчетом времени в минутах и секундах.
22
+ */
23
+ export declare const Timer: ({ expiryTimestamp, autoStart, onTimerEnd, className }: TProps) => import("react/jsx-runtime").JSX.Element;
24
+ export {};
@@ -0,0 +1,29 @@
1
+ import { jsxs } from "react/jsx-runtime";
2
+ import { c as classNames } from "../../index-CweZ_OcN.js";
3
+ import { useTimer } from "../../hooks/useTimer/index.js";
4
+ import '../../assets/Timer.css';const timer = "_timer_llwad_3";
5
+ const cls = {
6
+ timer
7
+ };
8
+ const Timer = ({
9
+ expiryTimestamp,
10
+ autoStart = false,
11
+ onTimerEnd,
12
+ className
13
+ }) => {
14
+ const { minutes, seconds } = useTimer({
15
+ expiryTimestamp,
16
+ onExpire: onTimerEnd,
17
+ autoStart
18
+ });
19
+ const formattedMinutes = String(minutes).padStart(2, "0");
20
+ const formattedSeconds = String(seconds).padStart(2, "0");
21
+ return /* @__PURE__ */ jsxs("div", { className: classNames(cls.timer, className), children: [
22
+ formattedMinutes,
23
+ ":",
24
+ formattedSeconds
25
+ ] });
26
+ };
27
+ export {
28
+ Timer
29
+ };
@@ -0,0 +1 @@
1
+ export { Timer } from './Timer';
@@ -0,0 +1,4 @@
1
+ import { Timer } from "./Timer.js";
2
+ export {
3
+ Timer
4
+ };
@@ -23,3 +23,4 @@ export { SelectSearch, ESelectSearchSize } from './SelectSearch';
23
23
  export type { TSelectSearchItem, TSelectSearchProps } from './SelectSearch';
24
24
  export { Switch } from './Switch';
25
25
  export type { TSwitchProps } from './Switch';
26
+ export { Timer } from './Timer';
@@ -22,6 +22,7 @@ import { EVoteSize } from "./Vote/constants.js";
22
22
  import { SelectSearch } from "./SelectSearch/SelectSearch.js";
23
23
  import { ESelectSearchSize } from "./SelectSearch/constants.js";
24
24
  import { Switch } from "./Switch/Switch.js";
25
+ import { Timer } from "./Timer/Timer.js";
25
26
  export {
26
27
  Button,
27
28
  DatePicker,
@@ -51,6 +52,7 @@ export {
51
52
  Slider,
52
53
  Steps,
53
54
  Switch,
55
+ Timer,
54
56
  Vote,
55
57
  getMaskedInputPhoneValue,
56
58
  getUnmaskedInputValue
@@ -1,2 +1,4 @@
1
1
  export { useMediaQuery, EMediaQuery } from './useMediaQuery';
2
2
  export { useLockBodyScroll } from './useLockBodyScroll';
3
+ export { useInterval } from './useInterval';
4
+ export { useTimer } from './useTimer';
@@ -1,8 +1,12 @@
1
1
  import { useMediaQuery } from "./useMediaQuery/useMediaQuery.js";
2
2
  import { EMediaQuery } from "./useMediaQuery/constants.js";
3
3
  import { useLockBodyScroll } from "./useLockBodyScroll/useLockBodyScroll.js";
4
+ import { useInterval } from "./useInterval/useInterval.js";
5
+ import { useTimer } from "./useTimer/index.js";
4
6
  export {
5
7
  EMediaQuery,
8
+ useInterval,
6
9
  useLockBodyScroll,
7
- useMediaQuery
10
+ useMediaQuery,
11
+ useTimer
8
12
  };
@@ -0,0 +1 @@
1
+ export { useInterval } from './useInterval';
@@ -0,0 +1,4 @@
1
+ import { useInterval } from "./useInterval.js";
2
+ export {
3
+ useInterval
4
+ };
@@ -0,0 +1 @@
1
+ export declare function useInterval(callback: VoidFunction, delay: number | null): void;
@@ -0,0 +1,17 @@
1
+ import { useRef, useEffect } from "react";
2
+ function useInterval(callback, delay) {
3
+ const callbackRef = useRef();
4
+ callbackRef.current = callback;
5
+ useEffect(() => {
6
+ if (!delay) {
7
+ return;
8
+ }
9
+ const interval = setInterval(() => {
10
+ callbackRef.current && callbackRef.current();
11
+ }, delay);
12
+ return () => clearInterval(interval);
13
+ }, [delay]);
14
+ }
15
+ export {
16
+ useInterval
17
+ };
@@ -0,0 +1,18 @@
1
+ export type TUserTimer = ReturnType<typeof useTimer>;
2
+ export type TUseTimerProps = {
3
+ expiryTimestamp?: number;
4
+ onExpire?: VoidFunction;
5
+ autoStart?: boolean;
6
+ };
7
+ export declare function useTimer({ expiryTimestamp: expiry, onExpire, autoStart }: TUseTimerProps): {
8
+ start: () => void;
9
+ pause: () => void;
10
+ resume: () => void;
11
+ restart: (newExpiryTimestamp: number, newAutoStart?: boolean) => void;
12
+ isRunning: boolean;
13
+ totalSeconds: number;
14
+ days: number;
15
+ hours: number;
16
+ minutes: number;
17
+ seconds: number;
18
+ };
@@ -0,0 +1,83 @@
1
+ import { useState, useCallback } from "react";
2
+ import { Time, Validate } from "./utils.js";
3
+ import { useInterval } from "../useInterval/useInterval.js";
4
+ const DEFAULT_DELAY = 1e3;
5
+ function getDelayFromExpiryTimestamp(expiryTimestamp) {
6
+ if (!Validate.expiryTimestamp(expiryTimestamp)) {
7
+ return null;
8
+ }
9
+ const seconds = Time.getSecondsFromExpiry(expiryTimestamp);
10
+ const extraMilliSeconds = Math.floor((seconds - Math.floor(seconds)) * 1e3);
11
+ return extraMilliSeconds > 0 ? extraMilliSeconds : DEFAULT_DELAY;
12
+ }
13
+ function useTimer({
14
+ expiryTimestamp: expiry,
15
+ onExpire,
16
+ autoStart = false
17
+ }) {
18
+ const [expiryTimestamp, setExpiryTimestamp] = useState(expiry);
19
+ const [seconds, setSeconds] = useState(
20
+ Time.getSecondsFromExpiry(expiry ?? 0)
21
+ );
22
+ const [isRunning, setIsRunning] = useState(autoStart);
23
+ const [didStart, setDidStart] = useState(autoStart);
24
+ const [delay, setDelay] = useState(getDelayFromExpiryTimestamp(expiry ?? 0));
25
+ const handleExpire = useCallback(() => {
26
+ Validate.onExpire(onExpire) && (onExpire == null ? void 0 : onExpire());
27
+ setIsRunning(false);
28
+ setDelay(null);
29
+ }, [onExpire]);
30
+ const pause = useCallback(() => {
31
+ setIsRunning(false);
32
+ }, []);
33
+ const restart = useCallback(
34
+ (newExpiryTimestamp, newAutoStart = true) => {
35
+ setDelay(getDelayFromExpiryTimestamp(newExpiryTimestamp));
36
+ setDidStart(newAutoStart);
37
+ setIsRunning(newAutoStart);
38
+ setExpiryTimestamp(newExpiryTimestamp);
39
+ setSeconds(Time.getSecondsFromExpiry(newExpiryTimestamp));
40
+ },
41
+ []
42
+ );
43
+ const resume = useCallback(() => {
44
+ const time = /* @__PURE__ */ new Date();
45
+ time.setMilliseconds(time.getMilliseconds() + seconds * 1e3);
46
+ restart(time.getTime(), true);
47
+ }, [seconds, restart]);
48
+ const start = useCallback(() => {
49
+ if (didStart) {
50
+ setSeconds(Time.getSecondsFromExpiry(expiryTimestamp ?? 0, false));
51
+ setIsRunning(true);
52
+ } else {
53
+ resume();
54
+ }
55
+ }, [expiryTimestamp, didStart, resume]);
56
+ useInterval(
57
+ () => {
58
+ if (delay !== DEFAULT_DELAY) {
59
+ setDelay(DEFAULT_DELAY);
60
+ }
61
+ const secondsValue = Time.getSecondsFromExpiry(
62
+ expiryTimestamp ?? 0,
63
+ false
64
+ );
65
+ setSeconds(secondsValue);
66
+ if (secondsValue <= 0) {
67
+ handleExpire();
68
+ }
69
+ },
70
+ isRunning ? delay : null
71
+ );
72
+ return {
73
+ ...Time.getTimeFromSeconds(seconds),
74
+ start,
75
+ pause,
76
+ resume,
77
+ restart,
78
+ isRunning
79
+ };
80
+ }
81
+ export {
82
+ useTimer
83
+ };
@@ -0,0 +1,18 @@
1
+ export type TUserTimer = ReturnType<typeof useTimer>;
2
+ export type TUseTimerProps = {
3
+ expiryTimestamp?: number;
4
+ onExpire?: VoidFunction;
5
+ autoStart?: boolean;
6
+ };
7
+ export declare function useTimer({ expiryTimestamp: expiry, onExpire, autoStart }: TUseTimerProps): {
8
+ start: () => void;
9
+ pause: () => void;
10
+ resume: () => void;
11
+ restart: (newExpiryTimestamp: number, newAutoStart?: boolean) => void;
12
+ isRunning: boolean;
13
+ totalSeconds: number;
14
+ days: number;
15
+ hours: number;
16
+ minutes: number;
17
+ seconds: number;
18
+ };
@@ -0,0 +1,87 @@
1
+ import { useState, useCallback } from "react";
2
+ import { Time, Validate, SECONDS_IN_MILLISECONDS } from "./utils.js";
3
+ import { useInterval } from "../useInterval/useInterval.js";
4
+ const DEFAULT_DELAY = 1e3;
5
+ function getDelayFromExpiryTimestamp(expiryTimestamp) {
6
+ if (!Validate.expiryTimestamp(expiryTimestamp)) {
7
+ return null;
8
+ }
9
+ const seconds = Time.getSecondsFromExpiry(expiryTimestamp);
10
+ const extraMilliSeconds = Math.floor(
11
+ (seconds - Math.floor(seconds)) * SECONDS_IN_MILLISECONDS
12
+ );
13
+ return extraMilliSeconds > 0 ? extraMilliSeconds : DEFAULT_DELAY;
14
+ }
15
+ function useTimer({
16
+ expiryTimestamp: expiry,
17
+ onExpire,
18
+ autoStart = true
19
+ }) {
20
+ const [expiryTimestamp, setExpiryTimestamp] = useState(expiry);
21
+ const [seconds, setSeconds] = useState(
22
+ Time.getSecondsFromExpiry(expiry ?? 0)
23
+ );
24
+ const [isRunning, setIsRunning] = useState(autoStart);
25
+ const [didStart, setDidStart] = useState(autoStart);
26
+ const [delay, setDelay] = useState(getDelayFromExpiryTimestamp(expiry ?? 0));
27
+ const handleExpire = useCallback(() => {
28
+ Validate.onExpire(onExpire) && (onExpire == null ? void 0 : onExpire());
29
+ setIsRunning(false);
30
+ setDelay(null);
31
+ }, [onExpire]);
32
+ const pause = useCallback(() => {
33
+ setIsRunning(false);
34
+ }, []);
35
+ const restart = useCallback(
36
+ (newExpiryTimestamp, newAutoStart = true) => {
37
+ setDelay(getDelayFromExpiryTimestamp(newExpiryTimestamp));
38
+ setDidStart(newAutoStart);
39
+ setIsRunning(newAutoStart);
40
+ setExpiryTimestamp(newExpiryTimestamp);
41
+ setSeconds(Time.getSecondsFromExpiry(newExpiryTimestamp));
42
+ },
43
+ []
44
+ );
45
+ const resume = useCallback(() => {
46
+ const time = /* @__PURE__ */ new Date();
47
+ time.setMilliseconds(
48
+ time.getMilliseconds() + seconds * SECONDS_IN_MILLISECONDS
49
+ );
50
+ restart(time.getTime(), true);
51
+ }, [seconds, restart]);
52
+ const start = useCallback(() => {
53
+ if (didStart) {
54
+ setSeconds(Time.getSecondsFromExpiry(expiryTimestamp ?? 0, false));
55
+ setIsRunning(true);
56
+ } else {
57
+ resume();
58
+ }
59
+ }, [expiryTimestamp, didStart, resume]);
60
+ useInterval(
61
+ () => {
62
+ if (delay !== DEFAULT_DELAY) {
63
+ setDelay(DEFAULT_DELAY);
64
+ }
65
+ const secondsValue = Time.getSecondsFromExpiry(
66
+ expiryTimestamp ?? 0,
67
+ false
68
+ );
69
+ setSeconds(secondsValue);
70
+ if (secondsValue <= 0) {
71
+ handleExpire();
72
+ }
73
+ },
74
+ isRunning ? delay : null
75
+ );
76
+ return {
77
+ ...Time.getTimeFromSeconds(seconds),
78
+ start,
79
+ pause,
80
+ resume,
81
+ restart,
82
+ isRunning
83
+ };
84
+ }
85
+ export {
86
+ useTimer
87
+ };
@@ -0,0 +1,24 @@
1
+ type TTimeObject = {
2
+ totalSeconds: number;
3
+ days: number;
4
+ hours: number;
5
+ minutes: number;
6
+ seconds: number;
7
+ };
8
+ type TFormattedTime = Omit<TTimeObject, 'totalSeconds' | 'days'>;
9
+ export declare const SECONDS_IN_MINUTE = 60;
10
+ export declare const SECONDS_IN_HOUR: number;
11
+ export declare const SECONDS_IN_DAY: number;
12
+ export declare const SECONDS_IN_MILLISECONDS = 1000;
13
+ export declare class Time {
14
+ static getTimeFromSeconds(secs: number): TTimeObject;
15
+ static getSecondsFromExpiry(expiry: number, shouldRound?: boolean): number;
16
+ static getSecondsFromPrevTime(prevTime: number, shouldRound: boolean): number;
17
+ static getSecondsFromTimeNow(): number;
18
+ static getFormattedTimeFromSeconds(totalSeconds: number): TFormattedTime;
19
+ }
20
+ export declare class Validate {
21
+ static expiryTimestamp(expiryTimestamp: number): boolean;
22
+ static onExpire(onExpire?: VoidFunction | null): boolean | null | undefined;
23
+ }
24
+ export {};
@@ -0,0 +1,88 @@
1
+ const SECONDS_IN_MINUTE = 60;
2
+ const SECONDS_IN_HOUR = 60 * SECONDS_IN_MINUTE;
3
+ const SECONDS_IN_DAY = SECONDS_IN_HOUR * 24;
4
+ const SECONDS_IN_MILLISECONDS = 1e3;
5
+ class Time {
6
+ static getTimeFromSeconds(secs) {
7
+ const totalSeconds = Math.ceil(secs);
8
+ const days = Math.floor(totalSeconds / SECONDS_IN_DAY);
9
+ const hours = Math.floor(totalSeconds % SECONDS_IN_DAY / SECONDS_IN_HOUR);
10
+ const minutes = Math.floor(
11
+ totalSeconds % SECONDS_IN_HOUR / SECONDS_IN_MINUTE
12
+ );
13
+ const seconds = Math.floor(totalSeconds % SECONDS_IN_MINUTE);
14
+ return {
15
+ totalSeconds,
16
+ seconds,
17
+ minutes,
18
+ hours,
19
+ days
20
+ };
21
+ }
22
+ static getSecondsFromExpiry(expiry, shouldRound) {
23
+ const now = (/* @__PURE__ */ new Date()).getTime();
24
+ const milliSecondsDistance = expiry - now;
25
+ if (milliSecondsDistance > 0) {
26
+ const val = milliSecondsDistance / SECONDS_IN_MILLISECONDS;
27
+ return shouldRound ? Math.round(val) : val;
28
+ }
29
+ return 0;
30
+ }
31
+ static getSecondsFromPrevTime(prevTime, shouldRound) {
32
+ const now = (/* @__PURE__ */ new Date()).getTime();
33
+ const milliSecondsDistance = now - prevTime;
34
+ if (milliSecondsDistance > 0) {
35
+ const val = milliSecondsDistance / SECONDS_IN_MILLISECONDS;
36
+ return shouldRound ? Math.round(val) : val;
37
+ }
38
+ return 0;
39
+ }
40
+ static getSecondsFromTimeNow() {
41
+ const now = /* @__PURE__ */ new Date();
42
+ const currentTimestamp = now.getTime();
43
+ const offset = now.getTimezoneOffset() * SECONDS_IN_MINUTE;
44
+ return currentTimestamp / SECONDS_IN_MILLISECONDS - offset;
45
+ }
46
+ static getFormattedTimeFromSeconds(totalSeconds) {
47
+ const {
48
+ seconds: secondsValue,
49
+ minutes,
50
+ hours
51
+ } = Time.getTimeFromSeconds(totalSeconds);
52
+ return {
53
+ seconds: secondsValue,
54
+ minutes,
55
+ hours
56
+ };
57
+ }
58
+ }
59
+ class Validate {
60
+ static expiryTimestamp(expiryTimestamp) {
61
+ const isValid = new Date(expiryTimestamp).getTime() > 0;
62
+ if (!isValid) {
63
+ console.warn(
64
+ "{ useTimer } Invalid expiryTimestamp settings",
65
+ expiryTimestamp
66
+ );
67
+ }
68
+ return isValid;
69
+ }
70
+ static onExpire(onExpire) {
71
+ const isValid = onExpire && typeof onExpire === "function";
72
+ if (onExpire && !isValid) {
73
+ console.warn(
74
+ " { useTimer } Invalid onExpire settings function",
75
+ onExpire
76
+ );
77
+ }
78
+ return isValid;
79
+ }
80
+ }
81
+ export {
82
+ SECONDS_IN_DAY,
83
+ SECONDS_IN_HOUR,
84
+ SECONDS_IN_MILLISECONDS,
85
+ SECONDS_IN_MINUTE,
86
+ Time,
87
+ Validate
88
+ };
package/dist/index.js CHANGED
@@ -22,9 +22,12 @@ import { EVoteSize } from "./components/Vote/constants.js";
22
22
  import { SelectSearch } from "./components/SelectSearch/SelectSearch.js";
23
23
  import { ESelectSearchSize } from "./components/SelectSearch/constants.js";
24
24
  import { Switch } from "./components/Switch/Switch.js";
25
+ import { Timer } from "./components/Timer/Timer.js";
25
26
  import { useMediaQuery } from "./hooks/useMediaQuery/useMediaQuery.js";
26
27
  import { EMediaQuery } from "./hooks/useMediaQuery/constants.js";
27
28
  import { useLockBodyScroll } from "./hooks/useLockBodyScroll/useLockBodyScroll.js";
29
+ import { useInterval } from "./hooks/useInterval/useInterval.js";
30
+ import { useTimer } from "./hooks/useTimer/index.js";
28
31
  import { Icon } from "./icons/Icon.js";
29
32
  import { formating } from "./utils/index.js";
30
33
  import './assets/index.css';export {
@@ -58,10 +61,13 @@ import './assets/index.css';export {
58
61
  Slider,
59
62
  Steps,
60
63
  Switch,
64
+ Timer,
61
65
  Vote,
62
66
  formating,
63
67
  getMaskedInputPhoneValue,
64
68
  getUnmaskedInputValue,
69
+ useInterval,
65
70
  useLockBodyScroll,
66
- useMediaQuery
71
+ useMediaQuery,
72
+ useTimer
67
73
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mimir-ui-kit",
3
3
  "private": false,
4
- "version": "1.8.1",
4
+ "version": "1.9.1",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {