@w3ux/hooks 1.2.1 → 1.3.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export * from "./useEffectIgnoreInitial";
2
2
  export * from "./useOnResize";
3
3
  export * from "./useOutsideAlerter";
4
4
  export * from "./useSize";
5
+ export * from "./useTimeleft";
package/cjs/index.js CHANGED
@@ -18,6 +18,7 @@ __exportStar(require("./useEffectIgnoreInitial"), exports);
18
18
  __exportStar(require("./useOnResize"), exports);
19
19
  __exportStar(require("./useOutsideAlerter"), exports);
20
20
  __exportStar(require("./useSize"), exports);
21
+ __exportStar(require("./useTimeleft"), exports);
21
22
 
22
23
  //# sourceMappingURL=index.js.map
23
24
 
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAGA,2DAAyC;AACzC,gDAA8B;AAC9B,sDAAoC;AACpC,4CAA0B","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from \"./useEffectIgnoreInitial\";\nexport * from \"./useOnResize\";\nexport * from \"./useOutsideAlerter\";\nexport * from \"./useSize\";\n"]}
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAGA,2DAAyC;AACzC,gDAA8B;AAC9B,sDAAoC;AACpC,4CAA0B;AAC1B,gDAA8B","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from \"./useEffectIgnoreInitial\";\nexport * from \"./useOnResize\";\nexport * from \"./useOutsideAlerter\";\nexport * from \"./useSize\";\nexport * from \"./useTimeleft\";\n"]}
@@ -0,0 +1,3 @@
1
+ import { TimeleftDuration } from "./types";
2
+ export declare const defaultDuration: TimeleftDuration;
3
+ export declare const defaultRefreshInterval = 60;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultRefreshInterval = exports.defaultDuration = void 0;
4
+ exports.defaultDuration = {
5
+ days: 0,
6
+ hours: 0,
7
+ minutes: 0,
8
+ seconds: 0,
9
+ lastMinute: false,
10
+ };
11
+ exports.defaultRefreshInterval = 60;
12
+
13
+ //# sourceMappingURL=defaults.js.map
14
+
15
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/defaults.ts"],"names":[],"mappings":";;;AAKa,QAAA,eAAe,GAAqB;IAC/C,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,KAAK;CAClB,CAAC;AAEW,QAAA,sBAAsB,GAAG,EAAE,CAAC","file":"defaults.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { TimeleftDuration } from \"./types\";\n\nexport const defaultDuration: TimeleftDuration = {\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n lastMinute: false,\n};\n\nexport const defaultRefreshInterval = 60;\n"]}
@@ -0,0 +1,5 @@
1
+ import type { TimeLeftAll, UseTimeleftProps } from "./types";
2
+ export declare const useTimeLeft: (props?: UseTimeleftProps) => {
3
+ setFromNow: (dateFrom: Date, dateTo: Date) => void;
4
+ timeleft: TimeLeftAll;
5
+ };
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTimeLeft = void 0;
4
+ const utils_1 = require("@w3ux/utils");
5
+ const react_1 = require("react");
6
+ const utils_2 = require("./utils");
7
+ const useTimeLeft = (props) => {
8
+ const depsTimeleft = (props === null || props === void 0 ? void 0 : props.depsTimeleft) || [];
9
+ const depsFormat = (props === null || props === void 0 ? void 0 : props.depsFormat) || [];
10
+ const inLastHour = () => {
11
+ const { days, hours } = (0, utils_2.getDuration)(toRef.current);
12
+ return !days && !hours;
13
+ };
14
+ const lastMinuteCountdown = () => {
15
+ const { seconds } = (0, utils_2.getDuration)(toRef.current);
16
+ if (!inLastHour()) {
17
+ return 60;
18
+ }
19
+ return seconds;
20
+ };
21
+ const getTimeleft = (c) => {
22
+ const { days, hours, minutes, seconds } = c || (0, utils_2.getDuration)(toRef.current);
23
+ const raw = {
24
+ days,
25
+ hours,
26
+ minutes,
27
+ };
28
+ if (!days && !hours) {
29
+ raw.seconds = seconds;
30
+ }
31
+ return {
32
+ raw,
33
+ };
34
+ };
35
+ const [to, setTo] = (0, react_1.useState)(null);
36
+ const toRef = (0, react_1.useRef)(to);
37
+ const [timeleft, setTimeleft] = (0, react_1.useState)(getTimeleft());
38
+ const [minInterval, setMinInterval] = (0, react_1.useState)(undefined);
39
+ const minIntervalRef = (0, react_1.useRef)(minInterval);
40
+ const [secInterval, setSecInterval] = (0, react_1.useState)(undefined);
41
+ const secIntervalRef = (0, react_1.useRef)(secInterval);
42
+ (0, react_1.useEffect)(() => {
43
+ setTimeleft(getTimeleft());
44
+ if (inLastHour()) {
45
+ if (!secIntervalRef.current) {
46
+ const interval = setInterval(() => {
47
+ if (!inLastHour()) {
48
+ clearInterval(secIntervalRef.current);
49
+ (0, utils_1.setStateWithRef)(undefined, setSecInterval, secIntervalRef);
50
+ }
51
+ setTimeleft(getTimeleft());
52
+ }, 1000);
53
+ (0, utils_1.setStateWithRef)(interval, setSecInterval, secIntervalRef);
54
+ }
55
+ }
56
+ else if (!minIntervalRef.current) {
57
+ const interval = setInterval(() => {
58
+ if (inLastHour()) {
59
+ clearInterval(minIntervalRef.current);
60
+ (0, utils_1.setStateWithRef)(undefined, setMinInterval, minIntervalRef);
61
+ }
62
+ setTimeleft(getTimeleft());
63
+ }, 60000);
64
+ (0, utils_1.setStateWithRef)(interval, setMinInterval, minIntervalRef);
65
+ }
66
+ }, [to, inLastHour(), lastMinuteCountdown(), ...depsTimeleft]);
67
+ (0, react_1.useEffect)(() => {
68
+ setTimeleft(getTimeleft());
69
+ }, [...depsFormat]);
70
+ (0, react_1.useEffect)(() => () => {
71
+ clearInterval(minInterval);
72
+ clearInterval(secInterval);
73
+ }, []);
74
+ const setFromNow = (dateFrom, dateTo) => {
75
+ setTimeleft(getTimeleft((0, utils_2.getDuration)(dateFrom)));
76
+ (0, utils_1.setStateWithRef)(dateTo, setTo, toRef);
77
+ };
78
+ return {
79
+ setFromNow,
80
+ timeleft,
81
+ };
82
+ };
83
+ exports.useTimeLeft = useTimeLeft;
84
+
85
+ //# sourceMappingURL=index.js.map
86
+
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { setStateWithRef } from \"@w3ux/utils\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type {\n TimeLeftAll,\n TimeLeftRaw,\n TimeleftDuration,\n UseTimeleftProps,\n} from \"./types\";\nimport { getDuration } from \"./utils\";\n\nexport const useTimeLeft = (props?: UseTimeleftProps) => {\n const depsTimeleft = props?.depsTimeleft || [];\n const depsFormat = props?.depsFormat || [];\n\n // check whether timeleft is within a minute of finishing.\n const inLastHour = () => {\n const { days, hours } = getDuration(toRef.current);\n return !days && !hours;\n };\n\n // get the amount of seconds left if timeleft is in the last minute.\n const lastMinuteCountdown = () => {\n const { seconds } = getDuration(toRef.current);\n if (!inLastHour()) {\n return 60;\n }\n return seconds;\n };\n\n // calculate resulting timeleft object from latest duration.\n const getTimeleft = (c?: TimeleftDuration): TimeLeftAll => {\n const { days, hours, minutes, seconds } = c || getDuration(toRef.current);\n const raw: TimeLeftRaw = {\n days,\n hours,\n minutes,\n };\n if (!days && !hours) {\n raw.seconds = seconds;\n }\n return {\n raw,\n };\n };\n\n // the end time as a date.\n const [to, setTo] = useState<Date | null>(null);\n const toRef = useRef(to);\n\n // resulting timeleft object to be returned.\n const [timeleft, setTimeleft] = useState<TimeLeftAll>(getTimeleft());\n\n // timeleft refresh intervals.\n const [minInterval, setMinInterval] = useState<\n ReturnType<typeof setInterval> | undefined\n >(undefined);\n const minIntervalRef = useRef(minInterval);\n\n const [secInterval, setSecInterval] = useState<\n ReturnType<typeof setInterval> | undefined\n >(undefined);\n const secIntervalRef = useRef(secInterval);\n\n // refresh effects.\n useEffect(() => {\n setTimeleft(getTimeleft());\n if (inLastHour()) {\n // refresh timeleft every second.\n if (!secIntervalRef.current) {\n const interval = setInterval(() => {\n if (!inLastHour()) {\n clearInterval(secIntervalRef.current);\n setStateWithRef(undefined, setSecInterval, secIntervalRef);\n }\n setTimeleft(getTimeleft());\n }, 1000);\n\n setStateWithRef(interval, setSecInterval, secIntervalRef);\n }\n }\n // refresh timeleft every minute.\n else if (!minIntervalRef.current) {\n const interval = setInterval(() => {\n if (inLastHour()) {\n clearInterval(minIntervalRef.current);\n setStateWithRef(undefined, setMinInterval, minIntervalRef);\n }\n setTimeleft(getTimeleft());\n }, 60000);\n setStateWithRef(interval, setMinInterval, minIntervalRef);\n }\n }, [to, inLastHour(), lastMinuteCountdown(), ...depsTimeleft]);\n\n // re-render the timeleft upon formatting changes.\n useEffect(() => {\n setTimeleft(getTimeleft());\n }, [...depsFormat]);\n\n // clear intervals on unmount\n useEffect(\n () => () => {\n clearInterval(minInterval);\n clearInterval(secInterval);\n },\n []\n );\n\n const setFromNow = (dateFrom: Date, dateTo: Date) => {\n setTimeleft(getTimeleft(getDuration(dateFrom)));\n setStateWithRef(dateTo, setTo, toRef);\n };\n\n return {\n setFromNow,\n timeleft,\n };\n};\n"]}
@@ -0,0 +1,29 @@
1
+ export interface UseTimeleftProps {
2
+ depsTimeleft: unknown[];
3
+ depsFormat: unknown[];
4
+ }
5
+ export interface TimeleftDuration {
6
+ days: number;
7
+ hours: number;
8
+ minutes: number;
9
+ seconds: number;
10
+ lastMinute: boolean;
11
+ }
12
+ export interface TimeLeftRaw {
13
+ days: number;
14
+ hours: number;
15
+ minutes: number;
16
+ seconds?: number;
17
+ }
18
+ export interface TimeLeftFormatted {
19
+ days: [number, string];
20
+ hours: [number, string];
21
+ minutes: [number, string];
22
+ seconds?: [number, string];
23
+ }
24
+ export interface TimeLeftAll {
25
+ raw: TimeLeftRaw;
26
+ }
27
+ export interface TimeleftHookProps {
28
+ refreshInterval: number;
29
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+
4
+ //# sourceMappingURL=types.js.map
5
+
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/types.ts"],"names":[],"mappings":"","file":"types.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport interface UseTimeleftProps {\n // Dependencies to trigger re-calculation of timeleft.\n depsTimeleft: unknown[];\n // Dependencies to trigger re-render of timeleft, e.g. if language switching occurs.\n depsFormat: unknown[];\n}\n\nexport interface TimeleftDuration {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n lastMinute: boolean;\n}\n\nexport interface TimeLeftRaw {\n days: number;\n hours: number;\n minutes: number;\n seconds?: number;\n}\n\nexport interface TimeLeftFormatted {\n days: [number, string];\n hours: [number, string];\n minutes: [number, string];\n seconds?: [number, string];\n}\n\nexport interface TimeLeftAll {\n raw: TimeLeftRaw;\n}\n\nexport interface TimeleftHookProps {\n refreshInterval: number;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { TimeleftDuration } from "./types";
2
+ export declare const getDuration: (toDate: Date | null) => TimeleftDuration;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDuration = void 0;
4
+ const date_fns_1 = require("date-fns");
5
+ const defaults_1 = require("./defaults");
6
+ const getDuration = (toDate) => {
7
+ if (!toDate) {
8
+ return defaults_1.defaultDuration;
9
+ }
10
+ if ((0, date_fns_1.getUnixTime)(toDate) <= (0, date_fns_1.getUnixTime)(new Date())) {
11
+ return defaults_1.defaultDuration;
12
+ }
13
+ toDate.setSeconds(toDate.getSeconds());
14
+ const d = (0, date_fns_1.intervalToDuration)({
15
+ start: Date.now(),
16
+ end: toDate,
17
+ });
18
+ const days = (0, date_fns_1.differenceInDays)(toDate, Date.now());
19
+ const hours = (d === null || d === void 0 ? void 0 : d.hours) || 0;
20
+ const minutes = (d === null || d === void 0 ? void 0 : d.minutes) || 0;
21
+ const seconds = (d === null || d === void 0 ? void 0 : d.seconds) || 0;
22
+ const lastHour = days === 0 && hours === 0;
23
+ const lastMinute = lastHour && minutes === 0;
24
+ return {
25
+ days,
26
+ hours,
27
+ minutes,
28
+ seconds,
29
+ lastMinute,
30
+ };
31
+ };
32
+ exports.getDuration = getDuration;
33
+
34
+ //# sourceMappingURL=utils.js.map
35
+
36
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/utils.ts"],"names":[],"mappings":";;;AAGA,uCAA6E;AAC7E,yCAA6C;AAItC,MAAM,WAAW,GAAG,CAAC,MAAmB,EAAoB,EAAE;IACnE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,0BAAe,CAAC;IACzB,CAAC;IACD,IAAI,IAAA,sBAAW,EAAC,MAAM,CAAC,IAAI,IAAA,sBAAW,EAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;QACnD,OAAO,0BAAe,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,IAAA,6BAAkB,EAAC;QAC3B,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE;QACjB,GAAG,EAAE,MAAM;KACZ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,IAAA,2BAAgB,EAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,KAAK,KAAI,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,KAAI,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,KAAI,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,QAAQ,IAAI,OAAO,KAAK,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI;QACJ,KAAK;QACL,OAAO;QACP,OAAO;QACP,UAAU;KACX,CAAC;AACJ,CAAC,CAAC;AA5BW,QAAA,WAAW,eA4BtB","file":"utils.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { differenceInDays, getUnixTime, intervalToDuration } from \"date-fns\";\nimport { defaultDuration } from \"./defaults\";\nimport type { TimeleftDuration } from \"./types\";\n\n// calculates the current timeleft duration.\nexport const getDuration = (toDate: Date | null): TimeleftDuration => {\n if (!toDate) {\n return defaultDuration;\n }\n if (getUnixTime(toDate) <= getUnixTime(new Date())) {\n return defaultDuration;\n }\n\n toDate.setSeconds(toDate.getSeconds());\n const d = intervalToDuration({\n start: Date.now(),\n end: toDate,\n });\n\n const days = differenceInDays(toDate, Date.now());\n const hours = d?.hours || 0;\n const minutes = d?.minutes || 0;\n const seconds = d?.seconds || 0;\n const lastHour = days === 0 && hours === 0;\n const lastMinute = lastHour && minutes === 0;\n\n return {\n days,\n hours,\n minutes,\n seconds,\n lastMinute,\n };\n};\n"]}
package/mjs/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export * from "./useEffectIgnoreInitial";
2
2
  export * from "./useOnResize";
3
3
  export * from "./useOutsideAlerter";
4
4
  export * from "./useSize";
5
+ export * from "./useTimeleft";
package/mjs/index.js CHANGED
@@ -2,6 +2,7 @@ export * from "./useEffectIgnoreInitial";
2
2
  export * from "./useOnResize";
3
3
  export * from "./useOutsideAlerter";
4
4
  export * from "./useSize";
5
+ export * from "./useTimeleft";
5
6
 
6
7
  //# sourceMappingURL=index.js.map
7
8
 
package/mjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from \"./useEffectIgnoreInitial\";\nexport * from \"./useOnResize\";\nexport * from \"./useOutsideAlerter\";\nexport * from \"./useSize\";\n"]}
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport * from \"./useEffectIgnoreInitial\";\nexport * from \"./useOnResize\";\nexport * from \"./useOutsideAlerter\";\nexport * from \"./useSize\";\nexport * from \"./useTimeleft\";\n"]}
@@ -0,0 +1,3 @@
1
+ import { TimeleftDuration } from "./types";
2
+ export declare const defaultDuration: TimeleftDuration;
3
+ export declare const defaultRefreshInterval = 60;
@@ -0,0 +1,12 @@
1
+ export const defaultDuration = {
2
+ days: 0,
3
+ hours: 0,
4
+ minutes: 0,
5
+ seconds: 0,
6
+ lastMinute: false,
7
+ };
8
+ export const defaultRefreshInterval = 60;
9
+
10
+ //# sourceMappingURL=defaults.js.map
11
+
12
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/defaults.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC","file":"defaults.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { TimeleftDuration } from \"./types\";\n\nexport const defaultDuration: TimeleftDuration = {\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n lastMinute: false,\n};\n\nexport const defaultRefreshInterval = 60;\n"]}
@@ -0,0 +1,5 @@
1
+ import type { TimeLeftAll, UseTimeleftProps } from "./types";
2
+ export declare const useTimeLeft: (props?: UseTimeleftProps) => {
3
+ setFromNow: (dateFrom: Date, dateTo: Date) => void;
4
+ timeleft: TimeLeftAll;
5
+ };
@@ -0,0 +1,83 @@
1
+ import { setStateWithRef } from "@w3ux/utils";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { getDuration } from "./utils";
4
+ export const useTimeLeft = (props) => {
5
+ const depsTimeleft = props?.depsTimeleft || [];
6
+ const depsFormat = props?.depsFormat || [];
7
+ const inLastHour = () => {
8
+ const { days, hours } = getDuration(toRef.current);
9
+ return !days && !hours;
10
+ };
11
+ const lastMinuteCountdown = () => {
12
+ const { seconds } = getDuration(toRef.current);
13
+ if (!inLastHour()) {
14
+ return 60;
15
+ }
16
+ return seconds;
17
+ };
18
+ const getTimeleft = (c) => {
19
+ const { days, hours, minutes, seconds } = c || getDuration(toRef.current);
20
+ const raw = {
21
+ days,
22
+ hours,
23
+ minutes,
24
+ };
25
+ if (!days && !hours) {
26
+ raw.seconds = seconds;
27
+ }
28
+ return {
29
+ raw,
30
+ };
31
+ };
32
+ const [to, setTo] = useState(null);
33
+ const toRef = useRef(to);
34
+ const [timeleft, setTimeleft] = useState(getTimeleft());
35
+ const [minInterval, setMinInterval] = useState(undefined);
36
+ const minIntervalRef = useRef(minInterval);
37
+ const [secInterval, setSecInterval] = useState(undefined);
38
+ const secIntervalRef = useRef(secInterval);
39
+ useEffect(() => {
40
+ setTimeleft(getTimeleft());
41
+ if (inLastHour()) {
42
+ if (!secIntervalRef.current) {
43
+ const interval = setInterval(() => {
44
+ if (!inLastHour()) {
45
+ clearInterval(secIntervalRef.current);
46
+ setStateWithRef(undefined, setSecInterval, secIntervalRef);
47
+ }
48
+ setTimeleft(getTimeleft());
49
+ }, 1000);
50
+ setStateWithRef(interval, setSecInterval, secIntervalRef);
51
+ }
52
+ }
53
+ else if (!minIntervalRef.current) {
54
+ const interval = setInterval(() => {
55
+ if (inLastHour()) {
56
+ clearInterval(minIntervalRef.current);
57
+ setStateWithRef(undefined, setMinInterval, minIntervalRef);
58
+ }
59
+ setTimeleft(getTimeleft());
60
+ }, 60000);
61
+ setStateWithRef(interval, setMinInterval, minIntervalRef);
62
+ }
63
+ }, [to, inLastHour(), lastMinuteCountdown(), ...depsTimeleft]);
64
+ useEffect(() => {
65
+ setTimeleft(getTimeleft());
66
+ }, [...depsFormat]);
67
+ useEffect(() => () => {
68
+ clearInterval(minInterval);
69
+ clearInterval(secInterval);
70
+ }, []);
71
+ const setFromNow = (dateFrom, dateTo) => {
72
+ setTimeleft(getTimeleft(getDuration(dateFrom)));
73
+ setStateWithRef(dateTo, setTo, toRef);
74
+ };
75
+ return {
76
+ setFromNow,
77
+ timeleft,
78
+ };
79
+ };
80
+
81
+ //# sourceMappingURL=index.js.map
82
+
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAOpD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAwB,EAAE,EAAE;IACtD,MAAM,YAAY,GAAG,KAAK,EAAE,YAAY,IAAI,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,KAAK,EAAE,UAAU,IAAI,EAAE,CAAC;IAG3C,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;IACzB,CAAC,CAAC;IAGF,MAAM,mBAAmB,GAAG,GAAG,EAAE;QAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAGF,MAAM,WAAW,GAAG,CAAC,CAAoB,EAAe,EAAE;QACxD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAgB;YACvB,IAAI;YACJ,KAAK;YACL,OAAO;SACR,CAAC;QACF,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACpB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;QACxB,CAAC;QACD,OAAO;YACL,GAAG;SACJ,CAAC;IACJ,CAAC,CAAC;IAGF,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAc,IAAI,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAGzB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAc,WAAW,EAAE,CAAC,CAAC;IAGrE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAE5C,SAAS,CAAC,CAAC;IACb,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAE5C,SAAS,CAAC,CAAC;IACb,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAG3C,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3B,IAAI,UAAU,EAAE,EAAE,CAAC;YAEjB,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;oBAChC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;wBAClB,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;wBACtC,eAAe,CAAC,SAAS,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;oBAC7D,CAAC;oBACD,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC7B,CAAC,EAAE,IAAI,CAAC,CAAC;gBAET,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;aAEI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;gBAChC,IAAI,UAAU,EAAE,EAAE,CAAC;oBACjB,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;oBACtC,eAAe,CAAC,SAAS,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;gBAC7D,CAAC;gBACD,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;YAC7B,CAAC,EAAE,KAAK,CAAC,CAAC;YACV,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,mBAAmB,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;IAG/D,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7B,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAGpB,SAAS,CACP,GAAG,EAAE,CAAC,GAAG,EAAE;QACT,aAAa,CAAC,WAAW,CAAC,CAAC;QAC3B,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,QAAc,EAAE,MAAY,EAAE,EAAE;QAClD,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAChD,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC;IAEF,OAAO;QACL,UAAU;QACV,QAAQ;KACT,CAAC;AACJ,CAAC,CAAC","file":"index.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { setStateWithRef } from \"@w3ux/utils\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type {\n TimeLeftAll,\n TimeLeftRaw,\n TimeleftDuration,\n UseTimeleftProps,\n} from \"./types\";\nimport { getDuration } from \"./utils\";\n\nexport const useTimeLeft = (props?: UseTimeleftProps) => {\n const depsTimeleft = props?.depsTimeleft || [];\n const depsFormat = props?.depsFormat || [];\n\n // check whether timeleft is within a minute of finishing.\n const inLastHour = () => {\n const { days, hours } = getDuration(toRef.current);\n return !days && !hours;\n };\n\n // get the amount of seconds left if timeleft is in the last minute.\n const lastMinuteCountdown = () => {\n const { seconds } = getDuration(toRef.current);\n if (!inLastHour()) {\n return 60;\n }\n return seconds;\n };\n\n // calculate resulting timeleft object from latest duration.\n const getTimeleft = (c?: TimeleftDuration): TimeLeftAll => {\n const { days, hours, minutes, seconds } = c || getDuration(toRef.current);\n const raw: TimeLeftRaw = {\n days,\n hours,\n minutes,\n };\n if (!days && !hours) {\n raw.seconds = seconds;\n }\n return {\n raw,\n };\n };\n\n // the end time as a date.\n const [to, setTo] = useState<Date | null>(null);\n const toRef = useRef(to);\n\n // resulting timeleft object to be returned.\n const [timeleft, setTimeleft] = useState<TimeLeftAll>(getTimeleft());\n\n // timeleft refresh intervals.\n const [minInterval, setMinInterval] = useState<\n ReturnType<typeof setInterval> | undefined\n >(undefined);\n const minIntervalRef = useRef(minInterval);\n\n const [secInterval, setSecInterval] = useState<\n ReturnType<typeof setInterval> | undefined\n >(undefined);\n const secIntervalRef = useRef(secInterval);\n\n // refresh effects.\n useEffect(() => {\n setTimeleft(getTimeleft());\n if (inLastHour()) {\n // refresh timeleft every second.\n if (!secIntervalRef.current) {\n const interval = setInterval(() => {\n if (!inLastHour()) {\n clearInterval(secIntervalRef.current);\n setStateWithRef(undefined, setSecInterval, secIntervalRef);\n }\n setTimeleft(getTimeleft());\n }, 1000);\n\n setStateWithRef(interval, setSecInterval, secIntervalRef);\n }\n }\n // refresh timeleft every minute.\n else if (!minIntervalRef.current) {\n const interval = setInterval(() => {\n if (inLastHour()) {\n clearInterval(minIntervalRef.current);\n setStateWithRef(undefined, setMinInterval, minIntervalRef);\n }\n setTimeleft(getTimeleft());\n }, 60000);\n setStateWithRef(interval, setMinInterval, minIntervalRef);\n }\n }, [to, inLastHour(), lastMinuteCountdown(), ...depsTimeleft]);\n\n // re-render the timeleft upon formatting changes.\n useEffect(() => {\n setTimeleft(getTimeleft());\n }, [...depsFormat]);\n\n // clear intervals on unmount\n useEffect(\n () => () => {\n clearInterval(minInterval);\n clearInterval(secInterval);\n },\n []\n );\n\n const setFromNow = (dateFrom: Date, dateTo: Date) => {\n setTimeleft(getTimeleft(getDuration(dateFrom)));\n setStateWithRef(dateTo, setTo, toRef);\n };\n\n return {\n setFromNow,\n timeleft,\n };\n};\n"]}
@@ -0,0 +1,29 @@
1
+ export interface UseTimeleftProps {
2
+ depsTimeleft: unknown[];
3
+ depsFormat: unknown[];
4
+ }
5
+ export interface TimeleftDuration {
6
+ days: number;
7
+ hours: number;
8
+ minutes: number;
9
+ seconds: number;
10
+ lastMinute: boolean;
11
+ }
12
+ export interface TimeLeftRaw {
13
+ days: number;
14
+ hours: number;
15
+ minutes: number;
16
+ seconds?: number;
17
+ }
18
+ export interface TimeLeftFormatted {
19
+ days: [number, string];
20
+ hours: [number, string];
21
+ minutes: [number, string];
22
+ seconds?: [number, string];
23
+ }
24
+ export interface TimeLeftAll {
25
+ raw: TimeLeftRaw;
26
+ }
27
+ export interface TimeleftHookProps {
28
+ refreshInterval: number;
29
+ }
@@ -0,0 +1,5 @@
1
+ export {};
2
+
3
+ //# sourceMappingURL=types.js.map
4
+
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/types.ts"],"names":[],"mappings":"","file":"types.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nexport interface UseTimeleftProps {\n // Dependencies to trigger re-calculation of timeleft.\n depsTimeleft: unknown[];\n // Dependencies to trigger re-render of timeleft, e.g. if language switching occurs.\n depsFormat: unknown[];\n}\n\nexport interface TimeleftDuration {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n lastMinute: boolean;\n}\n\nexport interface TimeLeftRaw {\n days: number;\n hours: number;\n minutes: number;\n seconds?: number;\n}\n\nexport interface TimeLeftFormatted {\n days: [number, string];\n hours: [number, string];\n minutes: [number, string];\n seconds?: [number, string];\n}\n\nexport interface TimeLeftAll {\n raw: TimeLeftRaw;\n}\n\nexport interface TimeleftHookProps {\n refreshInterval: number;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { TimeleftDuration } from "./types";
2
+ export declare const getDuration: (toDate: Date | null) => TimeleftDuration;
@@ -0,0 +1,32 @@
1
+ import { differenceInDays, getUnixTime, intervalToDuration } from "date-fns";
2
+ import { defaultDuration } from "./defaults";
3
+ export const getDuration = (toDate) => {
4
+ if (!toDate) {
5
+ return defaultDuration;
6
+ }
7
+ if (getUnixTime(toDate) <= getUnixTime(new Date())) {
8
+ return defaultDuration;
9
+ }
10
+ toDate.setSeconds(toDate.getSeconds());
11
+ const d = intervalToDuration({
12
+ start: Date.now(),
13
+ end: toDate,
14
+ });
15
+ const days = differenceInDays(toDate, Date.now());
16
+ const hours = d?.hours || 0;
17
+ const minutes = d?.minutes || 0;
18
+ const seconds = d?.seconds || 0;
19
+ const lastHour = days === 0 && hours === 0;
20
+ const lastMinute = lastHour && minutes === 0;
21
+ return {
22
+ days,
23
+ hours,
24
+ minutes,
25
+ seconds,
26
+ lastMinute,
27
+ };
28
+ };
29
+
30
+ //# sourceMappingURL=utils.js.map
31
+
32
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useTimeleft/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI7C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAmB,EAAoB,EAAE;IACnE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;QACnD,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,kBAAkB,CAAC;QAC3B,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE;QACjB,GAAG,EAAE,MAAM;KACZ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,QAAQ,IAAI,OAAO,KAAK,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI;QACJ,KAAK;QACL,OAAO;QACP,OAAO;QACP,UAAU;KACX,CAAC;AACJ,CAAC,CAAC","file":"utils.js","sourcesContent":["/* @license Copyright 2024 w3ux authors & contributors\nSPDX-License-Identifier: GPL-3.0-only */\n\nimport { differenceInDays, getUnixTime, intervalToDuration } from \"date-fns\";\nimport { defaultDuration } from \"./defaults\";\nimport type { TimeleftDuration } from \"./types\";\n\n// calculates the current timeleft duration.\nexport const getDuration = (toDate: Date | null): TimeleftDuration => {\n if (!toDate) {\n return defaultDuration;\n }\n if (getUnixTime(toDate) <= getUnixTime(new Date())) {\n return defaultDuration;\n }\n\n toDate.setSeconds(toDate.getSeconds());\n const d = intervalToDuration({\n start: Date.now(),\n end: toDate,\n });\n\n const days = differenceInDays(toDate, Date.now());\n const hours = d?.hours || 0;\n const minutes = d?.minutes || 0;\n const seconds = d?.seconds || 0;\n const lastHour = days === 0 && hours === 0;\n const lastMinute = lastHour && minutes === 0;\n\n return {\n days,\n hours,\n minutes,\n seconds,\n lastMinute,\n };\n};\n"]}
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@w3ux/hooks",
3
- "version": "1.2.1",
3
+ "version": "1.3.1-beta.0",
4
4
  "license": "GPL-3.0-only",
5
+ "dependencies": {
6
+ "@w3ux/utils": "^1.1.1-beta.9",
7
+ "date-fns": "^4.1.0"
8
+ },
5
9
  "main": "cjs/index.js",
6
10
  "module": "mjs/index.js",
7
11
  "exports": {