@zuzjs/ui 0.9.82 → 0.10.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/dist/cjs/comps/Crumb/index.d.ts +1 -1
- package/dist/cjs/comps/List/index.d.ts +1 -1
- package/dist/cjs/hooks/index.d.ts +1 -0
- package/dist/cjs/hooks/index.js +1 -0
- package/dist/cjs/hooks/useNextInterval.d.ts +14 -0
- package/dist/cjs/hooks/useNextInterval.js +54 -0
- package/dist/cjs/hooks/useSlider.d.ts +1 -1
- package/dist/esm/comps/Crumb/index.d.ts +1 -1
- package/dist/esm/comps/List/index.d.ts +1 -1
- package/dist/esm/hooks/index.d.ts +1 -0
- package/dist/esm/hooks/index.js +1 -0
- package/dist/esm/hooks/useNextInterval.d.ts +14 -0
- package/dist/esm/hooks/useNextInterval.js +54 -0
- package/dist/esm/hooks/useSlider.d.ts +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare const Crumb: import("react").ForwardRefExoticComponent<import("..").BoxProps & {
|
|
2
2
|
items: import("./types").CrumbItem[];
|
|
3
3
|
maxItems?: number;
|
|
4
|
-
} & import("react").RefAttributes<
|
|
4
|
+
} & import("react").RefAttributes<HTMLOListElement | HTMLUListElement>>;
|
|
5
5
|
export default Crumb;
|
|
@@ -6,5 +6,5 @@ declare const List: import("react").ForwardRefExoticComponent<import("../..").Zu
|
|
|
6
6
|
direction?: "cols" | "rows";
|
|
7
7
|
seperator?: import("react").ReactNode;
|
|
8
8
|
ol?: boolean;
|
|
9
|
-
} & import("react").RefAttributes<
|
|
9
|
+
} & import("react").RefAttributes<HTMLOListElement | HTMLUListElement>>;
|
|
10
10
|
export default List;
|
|
@@ -28,6 +28,7 @@ export { default as useScrollPhysics } from './useScrollPhysics';
|
|
|
28
28
|
export { default as useSheet } from './useSheet';
|
|
29
29
|
export { default as useShortcuts } from './useShortcuts';
|
|
30
30
|
export { default as useNetworkStatus } from './useNetworkStatus';
|
|
31
|
+
export { default as useNextInterval } from './useNextInterval';
|
|
31
32
|
export { default as usePosition } from './usePosition';
|
|
32
33
|
export { default as usePushNotifications, type PushNotificationsOptions, type PushNotificationsResult, type PushSubscriptionMeta } from './usePushNotifications';
|
|
33
34
|
export { default as useResizeObserver } from './useResizeObserver';
|
package/dist/cjs/hooks/index.js
CHANGED
|
@@ -29,6 +29,7 @@ export { default as useScrollPhysics } from './useScrollPhysics';
|
|
|
29
29
|
export { default as useSheet } from './useSheet';
|
|
30
30
|
export { default as useShortcuts } from './useShortcuts';
|
|
31
31
|
export { default as useNetworkStatus } from './useNetworkStatus';
|
|
32
|
+
export { default as useNextInterval } from './useNextInterval';
|
|
32
33
|
export { default as usePosition } from './usePosition';
|
|
33
34
|
export { default as usePushNotifications } from './usePushNotifications';
|
|
34
35
|
export { default as useResizeObserver } from './useResizeObserver';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Countdown {
|
|
2
|
+
minutes: number;
|
|
3
|
+
seconds: number;
|
|
4
|
+
formatted: string;
|
|
5
|
+
nextBoundary: Date;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* React hook that counts down to the next N-minute boundary.
|
|
9
|
+
*
|
|
10
|
+
* @param intervalMinutes The interval in minutes (e.g., 1, 5, 15, 30, 60)
|
|
11
|
+
* @returns Countdown info + next boundary time
|
|
12
|
+
*/
|
|
13
|
+
declare const useNextInterval: (intervalMinutes?: number) => Countdown;
|
|
14
|
+
export default useNextInterval;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that counts down to the next N-minute boundary.
|
|
4
|
+
*
|
|
5
|
+
* @param intervalMinutes The interval in minutes (e.g., 1, 5, 15, 30, 60)
|
|
6
|
+
* @returns Countdown info + next boundary time
|
|
7
|
+
*/
|
|
8
|
+
const useNextInterval = (intervalMinutes = 15) => {
|
|
9
|
+
if (intervalMinutes <= 0) {
|
|
10
|
+
throw new Error('intervalMinutes must be greater than 0');
|
|
11
|
+
}
|
|
12
|
+
const calculateNextBoundary = (now) => {
|
|
13
|
+
const next = new Date(now);
|
|
14
|
+
const minutes = next.getMinutes();
|
|
15
|
+
const remainder = minutes % intervalMinutes;
|
|
16
|
+
if (remainder === 0) {
|
|
17
|
+
// Exactly on a boundary → go to next one
|
|
18
|
+
next.setMinutes(minutes + intervalMinutes);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Round up to next boundary
|
|
22
|
+
next.setMinutes(minutes + (intervalMinutes - remainder));
|
|
23
|
+
}
|
|
24
|
+
// Reset seconds and milliseconds
|
|
25
|
+
next.setSeconds(0);
|
|
26
|
+
next.setMilliseconds(0);
|
|
27
|
+
return next;
|
|
28
|
+
};
|
|
29
|
+
const [nextBoundary, setNextBoundary] = useState(() => calculateNextBoundary(new Date()));
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const update = () => {
|
|
32
|
+
const now = new Date();
|
|
33
|
+
const next = calculateNextBoundary(now);
|
|
34
|
+
if (next.getTime() !== nextBoundary.getTime()) {
|
|
35
|
+
setNextBoundary(next);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
update(); // Initial sync
|
|
39
|
+
const interval = setInterval(update, 1000);
|
|
40
|
+
return () => clearInterval(interval);
|
|
41
|
+
}, [intervalMinutes, nextBoundary]);
|
|
42
|
+
const now = new Date();
|
|
43
|
+
const diffMs = Math.max(0, nextBoundary.getTime() - now.getTime());
|
|
44
|
+
const totalMinutes = Math.floor(diffMs / 60000);
|
|
45
|
+
const seconds = Math.floor((diffMs % 60000) / 1000);
|
|
46
|
+
const formatted = `${totalMinutes}m ${seconds.toString().padStart(2, '0')}s`;
|
|
47
|
+
return {
|
|
48
|
+
minutes: totalMinutes,
|
|
49
|
+
seconds,
|
|
50
|
+
formatted,
|
|
51
|
+
nextBoundary,
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export default useNextInterval;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare const Crumb: import("react").ForwardRefExoticComponent<import("..").BoxProps & {
|
|
2
2
|
items: import("./types").CrumbItem[];
|
|
3
3
|
maxItems?: number;
|
|
4
|
-
} & import("react").RefAttributes<
|
|
4
|
+
} & import("react").RefAttributes<HTMLOListElement | HTMLUListElement>>;
|
|
5
5
|
export default Crumb;
|
|
@@ -6,5 +6,5 @@ declare const List: import("react").ForwardRefExoticComponent<import("../..").Zu
|
|
|
6
6
|
direction?: "cols" | "rows";
|
|
7
7
|
seperator?: import("react").ReactNode;
|
|
8
8
|
ol?: boolean;
|
|
9
|
-
} & import("react").RefAttributes<
|
|
9
|
+
} & import("react").RefAttributes<HTMLOListElement | HTMLUListElement>>;
|
|
10
10
|
export default List;
|
|
@@ -28,6 +28,7 @@ export { default as useScrollPhysics } from './useScrollPhysics';
|
|
|
28
28
|
export { default as useSheet } from './useSheet';
|
|
29
29
|
export { default as useShortcuts } from './useShortcuts';
|
|
30
30
|
export { default as useNetworkStatus } from './useNetworkStatus';
|
|
31
|
+
export { default as useNextInterval } from './useNextInterval';
|
|
31
32
|
export { default as usePosition } from './usePosition';
|
|
32
33
|
export { default as usePushNotifications, type PushNotificationsOptions, type PushNotificationsResult, type PushSubscriptionMeta } from './usePushNotifications';
|
|
33
34
|
export { default as useResizeObserver } from './useResizeObserver';
|
package/dist/esm/hooks/index.js
CHANGED
|
@@ -29,6 +29,7 @@ export { default as useScrollPhysics } from './useScrollPhysics';
|
|
|
29
29
|
export { default as useSheet } from './useSheet';
|
|
30
30
|
export { default as useShortcuts } from './useShortcuts';
|
|
31
31
|
export { default as useNetworkStatus } from './useNetworkStatus';
|
|
32
|
+
export { default as useNextInterval } from './useNextInterval';
|
|
32
33
|
export { default as usePosition } from './usePosition';
|
|
33
34
|
export { default as usePushNotifications } from './usePushNotifications';
|
|
34
35
|
export { default as useResizeObserver } from './useResizeObserver';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Countdown {
|
|
2
|
+
minutes: number;
|
|
3
|
+
seconds: number;
|
|
4
|
+
formatted: string;
|
|
5
|
+
nextBoundary: Date;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* React hook that counts down to the next N-minute boundary.
|
|
9
|
+
*
|
|
10
|
+
* @param intervalMinutes The interval in minutes (e.g., 1, 5, 15, 30, 60)
|
|
11
|
+
* @returns Countdown info + next boundary time
|
|
12
|
+
*/
|
|
13
|
+
declare const useNextInterval: (intervalMinutes?: number) => Countdown;
|
|
14
|
+
export default useNextInterval;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that counts down to the next N-minute boundary.
|
|
4
|
+
*
|
|
5
|
+
* @param intervalMinutes The interval in minutes (e.g., 1, 5, 15, 30, 60)
|
|
6
|
+
* @returns Countdown info + next boundary time
|
|
7
|
+
*/
|
|
8
|
+
const useNextInterval = (intervalMinutes = 15) => {
|
|
9
|
+
if (intervalMinutes <= 0) {
|
|
10
|
+
throw new Error('intervalMinutes must be greater than 0');
|
|
11
|
+
}
|
|
12
|
+
const calculateNextBoundary = (now) => {
|
|
13
|
+
const next = new Date(now);
|
|
14
|
+
const minutes = next.getMinutes();
|
|
15
|
+
const remainder = minutes % intervalMinutes;
|
|
16
|
+
if (remainder === 0) {
|
|
17
|
+
// Exactly on a boundary → go to next one
|
|
18
|
+
next.setMinutes(minutes + intervalMinutes);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Round up to next boundary
|
|
22
|
+
next.setMinutes(minutes + (intervalMinutes - remainder));
|
|
23
|
+
}
|
|
24
|
+
// Reset seconds and milliseconds
|
|
25
|
+
next.setSeconds(0);
|
|
26
|
+
next.setMilliseconds(0);
|
|
27
|
+
return next;
|
|
28
|
+
};
|
|
29
|
+
const [nextBoundary, setNextBoundary] = useState(() => calculateNextBoundary(new Date()));
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const update = () => {
|
|
32
|
+
const now = new Date();
|
|
33
|
+
const next = calculateNextBoundary(now);
|
|
34
|
+
if (next.getTime() !== nextBoundary.getTime()) {
|
|
35
|
+
setNextBoundary(next);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
update(); // Initial sync
|
|
39
|
+
const interval = setInterval(update, 1000);
|
|
40
|
+
return () => clearInterval(interval);
|
|
41
|
+
}, [intervalMinutes, nextBoundary]);
|
|
42
|
+
const now = new Date();
|
|
43
|
+
const diffMs = Math.max(0, nextBoundary.getTime() - now.getTime());
|
|
44
|
+
const totalMinutes = Math.floor(diffMs / 60000);
|
|
45
|
+
const seconds = Math.floor((diffMs % 60000) / 1000);
|
|
46
|
+
const formatted = `${totalMinutes}m ${seconds.toString().padStart(2, '0')}s`;
|
|
47
|
+
return {
|
|
48
|
+
minutes: totalMinutes,
|
|
49
|
+
seconds,
|
|
50
|
+
formatted,
|
|
51
|
+
nextBoundary,
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export default useNextInterval;
|