deepsea-components 5.17.13 → 5.17.15
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/components/AutoScroll.cjs +29 -25
- package/dist/components/AutoScroll.d.ts +9 -4
- package/dist/components/AutoScroll.js +30 -26
- package/dist/components/Scroll.cjs +6 -10
- package/dist/components/Scroll.d.ts +3 -3
- package/dist/components/Scroll.js +7 -11
- package/package.json +6 -7
- package/src/components/AutoScroll.tsx +56 -45
- package/src/components/Scroll.tsx +18 -10
|
@@ -34,15 +34,14 @@ const external_deepsea_tools_namespaceObject = require("deepsea-tools");
|
|
|
34
34
|
const external_soda_hooks_namespaceObject = require("soda-hooks");
|
|
35
35
|
const index_cjs_namespaceObject = require("../utils/index.cjs");
|
|
36
36
|
const external_Scroll_cjs_namespaceObject = require("./Scroll.cjs");
|
|
37
|
-
const AutoScroll =
|
|
38
|
-
const
|
|
37
|
+
const AutoScroll = ({ ref, count, itemSize, animation = 1000, duration = 3000, onMouseEnter, onMouseLeave, gap = 0, containerClassName, containerStyle, children, playOnMouseEnter, scrollbar, paused, direction = "vertical", ...rest })=>{
|
|
38
|
+
const isVertical = "vertical" === direction;
|
|
39
39
|
const bar = (0, external_react_namespaceObject.useRef)(null);
|
|
40
40
|
const timeout = (0, external_react_namespaceObject.useRef)(void 0);
|
|
41
41
|
const ele = (0, external_react_namespaceObject.useRef)(null);
|
|
42
42
|
const size = (0, external_soda_hooks_namespaceObject.useSize)(ele);
|
|
43
43
|
const pausedRef = (0, external_react_namespaceObject.useRef)(false);
|
|
44
|
-
const
|
|
45
|
-
pausedProps.current = paused;
|
|
44
|
+
const getPaused = (0, external_react_namespaceObject.useEffectEvent)(()=>paused);
|
|
46
45
|
(0, external_react_namespaceObject.useImperativeHandle)(ref, ()=>ele.current, []);
|
|
47
46
|
(0, external_react_namespaceObject.useImperativeHandle)(scrollbar, ()=>bar.current, []);
|
|
48
47
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
@@ -53,23 +52,24 @@ const AutoScroll = /*#__PURE__*/ (0, external_react_namespaceObject.forwardRef)(
|
|
|
53
52
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
54
53
|
var _bar_current;
|
|
55
54
|
if (!size || 0 === count) return;
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
55
|
+
const containerSize = isVertical ? size.height : size.width;
|
|
56
|
+
if (0 === itemSize || 0 === containerSize) return;
|
|
57
|
+
const range = (0, external_deepsea_tools_namespaceObject.getArray)(count, (index)=>(itemSize + gap) * (index + 1) - (index === count - 1 ? gap : 0));
|
|
58
|
+
const scrollLength = range.at(-1);
|
|
59
|
+
if (containerSize >= scrollLength) return;
|
|
60
60
|
function scroll(target) {
|
|
61
61
|
clearTimeout(timeout.current);
|
|
62
62
|
timeout.current = setTimeout(()=>{
|
|
63
63
|
var _bar_current;
|
|
64
|
-
if (pausedRef.current ||
|
|
65
|
-
null == (_bar_current = bar.current) || _bar_current.scrollTo(0, target, animation);
|
|
64
|
+
if (pausedRef.current || getPaused()) return scroll(target);
|
|
65
|
+
null == (_bar_current = bar.current) || _bar_current.scrollTo(isVertical ? 0 : target, isVertical ? target : 0, animation);
|
|
66
66
|
}, duration);
|
|
67
67
|
}
|
|
68
68
|
scroll(range[0]);
|
|
69
69
|
function listener(status) {
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const target =
|
|
70
|
+
const offset = isVertical ? status.offset.y : status.offset.x;
|
|
71
|
+
const scrollToEnd = Math.abs(offset + containerSize - scrollLength) / itemSize <= 0.05;
|
|
72
|
+
const target = scrollToEnd ? 0 : range.find((item)=>item > offset);
|
|
73
73
|
scroll(target);
|
|
74
74
|
}
|
|
75
75
|
null == (_bar_current = bar.current) || _bar_current.addListener(listener);
|
|
@@ -82,10 +82,11 @@ const AutoScroll = /*#__PURE__*/ (0, external_react_namespaceObject.forwardRef)(
|
|
|
82
82
|
}, [
|
|
83
83
|
size,
|
|
84
84
|
count,
|
|
85
|
-
|
|
85
|
+
itemSize,
|
|
86
86
|
gap,
|
|
87
87
|
duration,
|
|
88
|
-
animation
|
|
88
|
+
animation,
|
|
89
|
+
isVertical
|
|
89
90
|
]);
|
|
90
91
|
function onContainerMouseEnter(e) {
|
|
91
92
|
if (playOnMouseEnter) return;
|
|
@@ -97,6 +98,15 @@ const AutoScroll = /*#__PURE__*/ (0, external_react_namespaceObject.forwardRef)(
|
|
|
97
98
|
pausedRef.current = false;
|
|
98
99
|
null == onMouseLeave || onMouseLeave(e);
|
|
99
100
|
}
|
|
101
|
+
const containerStyle2 = (0, css_namespaceObject.css)`
|
|
102
|
+
display: flex;
|
|
103
|
+
flex-direction: var(--flex-direction, column);
|
|
104
|
+
gap: var(--gap, 0);
|
|
105
|
+
|
|
106
|
+
& > * {
|
|
107
|
+
flex: none;
|
|
108
|
+
}
|
|
109
|
+
`;
|
|
100
110
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Scroll_cjs_namespaceObject.Scroll, {
|
|
101
111
|
ref: ele,
|
|
102
112
|
scrollbar: bar,
|
|
@@ -104,21 +114,15 @@ const AutoScroll = /*#__PURE__*/ (0, external_react_namespaceObject.forwardRef)(
|
|
|
104
114
|
onMouseLeave: onContainerMouseLeave,
|
|
105
115
|
...rest,
|
|
106
116
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
107
|
-
className: (0, external_deepsea_tools_namespaceObject.clsx)(
|
|
108
|
-
display: flex;
|
|
109
|
-
flex-direction: column;
|
|
110
|
-
gap: var(--gap, 0);
|
|
111
|
-
& > * {
|
|
112
|
-
flex: none;
|
|
113
|
-
}
|
|
114
|
-
`, containerClassName),
|
|
117
|
+
className: (0, external_deepsea_tools_namespaceObject.clsx)(containerStyle2, containerClassName),
|
|
115
118
|
style: (0, index_cjs_namespaceObject.transformCSSVariable)({
|
|
116
|
-
gap: (0, index_cjs_namespaceObject.px)(gap)
|
|
119
|
+
gap: (0, index_cjs_namespaceObject.px)(gap),
|
|
120
|
+
flexDirection: isVertical ? "column" : "row"
|
|
117
121
|
}, containerStyle),
|
|
118
122
|
children: children
|
|
119
123
|
})
|
|
120
124
|
});
|
|
121
|
-
}
|
|
125
|
+
};
|
|
122
126
|
exports.AutoScroll = __webpack_exports__.AutoScroll;
|
|
123
127
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
124
128
|
"AutoScroll"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { CSSProperties } from "react";
|
|
1
|
+
import { CSSProperties, FC } from "react";
|
|
2
2
|
import { ScrollProps } from "./Scroll";
|
|
3
3
|
export interface AutoScrollProps extends ScrollProps {
|
|
4
4
|
/** 轮播元素的个数 */
|
|
5
5
|
count: number;
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/** 轮播元素的尺寸(垂直滚动时为高度,水平滚动时为宽度) */
|
|
7
|
+
itemSize: number;
|
|
8
8
|
/**
|
|
9
9
|
* 轮播动画的时间,单位毫秒
|
|
10
10
|
* @default 1000
|
|
@@ -24,6 +24,11 @@ export interface AutoScrollProps extends ScrollProps {
|
|
|
24
24
|
containerClassName?: string;
|
|
25
25
|
/** 容器样式 */
|
|
26
26
|
containerStyle?: CSSProperties;
|
|
27
|
+
/**
|
|
28
|
+
* 滚动方向
|
|
29
|
+
* @default vertical
|
|
30
|
+
*/
|
|
31
|
+
direction?: "vertical" | "horizontal";
|
|
27
32
|
/**
|
|
28
33
|
* 在鼠标移入时是否继续播放
|
|
29
34
|
* @default false
|
|
@@ -35,4 +40,4 @@ export interface AutoScrollProps extends ScrollProps {
|
|
|
35
40
|
*/
|
|
36
41
|
paused?: boolean;
|
|
37
42
|
}
|
|
38
|
-
export declare const AutoScroll:
|
|
43
|
+
export declare const AutoScroll: FC<AutoScrollProps>;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useEffect, useEffectEvent, useImperativeHandle, useRef } from "react";
|
|
4
4
|
import { css } from "@emotion/css";
|
|
5
5
|
import { clsx, getArray } from "deepsea-tools";
|
|
6
6
|
import { useSize } from "soda-hooks";
|
|
7
7
|
import { px, transformCSSVariable } from "../utils/index.js";
|
|
8
8
|
import { Scroll } from "./Scroll.js";
|
|
9
|
-
const AutoScroll =
|
|
10
|
-
const
|
|
9
|
+
const AutoScroll = ({ ref, count, itemSize, animation = 1000, duration = 3000, onMouseEnter, onMouseLeave, gap = 0, containerClassName, containerStyle, children, playOnMouseEnter, scrollbar, paused, direction = "vertical", ...rest })=>{
|
|
10
|
+
const isVertical = "vertical" === direction;
|
|
11
11
|
const bar = useRef(null);
|
|
12
12
|
const timeout = useRef(void 0);
|
|
13
13
|
const ele = useRef(null);
|
|
14
14
|
const size = useSize(ele);
|
|
15
15
|
const pausedRef = useRef(false);
|
|
16
|
-
const
|
|
17
|
-
pausedProps.current = paused;
|
|
16
|
+
const getPaused = useEffectEvent(()=>paused);
|
|
18
17
|
useImperativeHandle(ref, ()=>ele.current, []);
|
|
19
18
|
useImperativeHandle(scrollbar, ()=>bar.current, []);
|
|
20
19
|
useEffect(()=>{
|
|
@@ -25,23 +24,24 @@ const AutoScroll = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
25
24
|
useEffect(()=>{
|
|
26
25
|
var _bar_current;
|
|
27
26
|
if (!size || 0 === count) return;
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
27
|
+
const containerSize = isVertical ? size.height : size.width;
|
|
28
|
+
if (0 === itemSize || 0 === containerSize) return;
|
|
29
|
+
const range = getArray(count, (index)=>(itemSize + gap) * (index + 1) - (index === count - 1 ? gap : 0));
|
|
30
|
+
const scrollLength = range.at(-1);
|
|
31
|
+
if (containerSize >= scrollLength) return;
|
|
32
32
|
function scroll(target) {
|
|
33
33
|
clearTimeout(timeout.current);
|
|
34
34
|
timeout.current = setTimeout(()=>{
|
|
35
35
|
var _bar_current;
|
|
36
|
-
if (pausedRef.current ||
|
|
37
|
-
null == (_bar_current = bar.current) || _bar_current.scrollTo(0, target, animation);
|
|
36
|
+
if (pausedRef.current || getPaused()) return scroll(target);
|
|
37
|
+
null == (_bar_current = bar.current) || _bar_current.scrollTo(isVertical ? 0 : target, isVertical ? target : 0, animation);
|
|
38
38
|
}, duration);
|
|
39
39
|
}
|
|
40
40
|
scroll(range[0]);
|
|
41
41
|
function listener(status) {
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const target =
|
|
42
|
+
const offset = isVertical ? status.offset.y : status.offset.x;
|
|
43
|
+
const scrollToEnd = Math.abs(offset + containerSize - scrollLength) / itemSize <= 0.05;
|
|
44
|
+
const target = scrollToEnd ? 0 : range.find((item)=>item > offset);
|
|
45
45
|
scroll(target);
|
|
46
46
|
}
|
|
47
47
|
null == (_bar_current = bar.current) || _bar_current.addListener(listener);
|
|
@@ -54,10 +54,11 @@ const AutoScroll = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
54
54
|
}, [
|
|
55
55
|
size,
|
|
56
56
|
count,
|
|
57
|
-
|
|
57
|
+
itemSize,
|
|
58
58
|
gap,
|
|
59
59
|
duration,
|
|
60
|
-
animation
|
|
60
|
+
animation,
|
|
61
|
+
isVertical
|
|
61
62
|
]);
|
|
62
63
|
function onContainerMouseEnter(e) {
|
|
63
64
|
if (playOnMouseEnter) return;
|
|
@@ -69,6 +70,15 @@ const AutoScroll = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
69
70
|
pausedRef.current = false;
|
|
70
71
|
null == onMouseLeave || onMouseLeave(e);
|
|
71
72
|
}
|
|
73
|
+
const containerStyle2 = css`
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: var(--flex-direction, column);
|
|
76
|
+
gap: var(--gap, 0);
|
|
77
|
+
|
|
78
|
+
& > * {
|
|
79
|
+
flex: none;
|
|
80
|
+
}
|
|
81
|
+
`;
|
|
72
82
|
return /*#__PURE__*/ jsx(Scroll, {
|
|
73
83
|
ref: ele,
|
|
74
84
|
scrollbar: bar,
|
|
@@ -76,19 +86,13 @@ const AutoScroll = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
76
86
|
onMouseLeave: onContainerMouseLeave,
|
|
77
87
|
...rest,
|
|
78
88
|
children: /*#__PURE__*/ jsx("div", {
|
|
79
|
-
className: clsx(
|
|
80
|
-
display: flex;
|
|
81
|
-
flex-direction: column;
|
|
82
|
-
gap: var(--gap, 0);
|
|
83
|
-
& > * {
|
|
84
|
-
flex: none;
|
|
85
|
-
}
|
|
86
|
-
`, containerClassName),
|
|
89
|
+
className: clsx(containerStyle2, containerClassName),
|
|
87
90
|
style: transformCSSVariable({
|
|
88
|
-
gap: px(gap)
|
|
91
|
+
gap: px(gap),
|
|
92
|
+
flexDirection: isVertical ? "column" : "row"
|
|
89
93
|
}, containerStyle),
|
|
90
94
|
children: children
|
|
91
95
|
})
|
|
92
96
|
});
|
|
93
|
-
}
|
|
97
|
+
};
|
|
94
98
|
export { AutoScroll };
|
|
@@ -87,9 +87,7 @@ var __webpack_exports__ = {};
|
|
|
87
87
|
return smooth_scrollbar_interfaces__WEBPACK_IMPORTED_MODULE_6__[key];
|
|
88
88
|
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
89
89
|
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
90
|
-
const Scroll =
|
|
91
|
-
const { children, options, className, style, scrollbar, onScrollbar, ...rest } = props;
|
|
92
|
-
const { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = options || {};
|
|
90
|
+
const Scroll = ({ ref, children, options: { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = {}, className, scrollbar, onScrollbar, style, ...rest })=>{
|
|
93
91
|
const ele = (0, react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
94
92
|
const bar = (0, react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
95
93
|
(0, react__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect)(()=>{
|
|
@@ -101,17 +99,15 @@ var __webpack_exports__ = {};
|
|
|
101
99
|
}, []);
|
|
102
100
|
(0, react__WEBPACK_IMPORTED_MODULE_1__.useImperativeHandle)(ref, ()=>ele.current, []);
|
|
103
101
|
(0, react__WEBPACK_IMPORTED_MODULE_1__.useImperativeHandle)(scrollbar, ()=>bar.current, []);
|
|
102
|
+
const onScrollbarListener = (0, react__WEBPACK_IMPORTED_MODULE_1__.useEffectEvent)(onScrollbar ?? (()=>void 0));
|
|
104
103
|
(0, react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{
|
|
105
104
|
var _bar_current;
|
|
106
|
-
|
|
107
|
-
null == (_bar_current = bar.current) || _bar_current.addListener(onScrollbar);
|
|
105
|
+
null == (_bar_current = bar.current) || _bar_current.addListener(onScrollbarListener);
|
|
108
106
|
return ()=>{
|
|
109
107
|
var _bar_current;
|
|
110
|
-
return null == (_bar_current = bar.current) ? void 0 : _bar_current.removeListener(
|
|
108
|
+
return null == (_bar_current = bar.current) ? void 0 : _bar_current.removeListener(onScrollbarListener);
|
|
111
109
|
};
|
|
112
|
-
}, [
|
|
113
|
-
onScrollbar
|
|
114
|
-
]);
|
|
110
|
+
}, []);
|
|
115
111
|
const style2 = (0, _emotion_css__WEBPACK_IMPORTED_MODULE_2__.css)`
|
|
116
112
|
.scrollbar-track.scrollbar-track-x {
|
|
117
113
|
${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""}
|
|
@@ -147,7 +143,7 @@ var __webpack_exports__ = {};
|
|
|
147
143
|
...rest,
|
|
148
144
|
children: children
|
|
149
145
|
});
|
|
150
|
-
}
|
|
146
|
+
};
|
|
151
147
|
})();
|
|
152
148
|
exports.Scroll = __webpack_exports__.Scroll;
|
|
153
149
|
exports.Scrollbar = __webpack_exports__.Scrollbar;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties,
|
|
1
|
+
import { ComponentProps, CSSProperties, FC, ForwardedRef } from "react";
|
|
2
2
|
import Scrollbar from "smooth-scrollbar";
|
|
3
3
|
import type { ScrollbarOptions, ScrollListener } from "smooth-scrollbar/interfaces";
|
|
4
4
|
export { default as Scrollbar } from "smooth-scrollbar";
|
|
@@ -13,7 +13,7 @@ export interface ScrollOptions extends Partial<ScrollbarOptions> {
|
|
|
13
13
|
/** 滚动条背景颜色 */
|
|
14
14
|
trackColor?: CSSProperties["backgroundColor"];
|
|
15
15
|
}
|
|
16
|
-
export interface ScrollProps extends
|
|
16
|
+
export interface ScrollProps extends ComponentProps<"div"> {
|
|
17
17
|
/** 滚动的配置 */
|
|
18
18
|
options?: ScrollOptions;
|
|
19
19
|
/** 滚动条实例 */
|
|
@@ -21,4 +21,4 @@ export interface ScrollProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
21
21
|
/** 滚动条滚动事件 */
|
|
22
22
|
onScrollbar?: ScrollListener;
|
|
23
23
|
}
|
|
24
|
-
export declare const Scroll:
|
|
24
|
+
export declare const Scroll: FC<ScrollProps>;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useEffect, useEffectEvent, useImperativeHandle, useLayoutEffect, useRef } from "react";
|
|
4
4
|
import { css } from "@emotion/css";
|
|
5
5
|
import { clsx } from "deepsea-tools";
|
|
6
6
|
import smooth_scrollbar from "smooth-scrollbar";
|
|
7
7
|
import { px, transformCSSVariable } from "../utils/index.js";
|
|
8
8
|
export * from "smooth-scrollbar/interfaces";
|
|
9
|
-
const Scroll =
|
|
10
|
-
const { children, options, className, style, scrollbar, onScrollbar, ...rest } = props;
|
|
11
|
-
const { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = options || {};
|
|
9
|
+
const Scroll = ({ ref, children, options: { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = {}, className, scrollbar, onScrollbar, style, ...rest })=>{
|
|
12
10
|
const ele = useRef(null);
|
|
13
11
|
const bar = useRef(null);
|
|
14
12
|
useLayoutEffect(()=>{
|
|
@@ -20,17 +18,15 @@ const Scroll = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
20
18
|
}, []);
|
|
21
19
|
useImperativeHandle(ref, ()=>ele.current, []);
|
|
22
20
|
useImperativeHandle(scrollbar, ()=>bar.current, []);
|
|
21
|
+
const onScrollbarListener = useEffectEvent(onScrollbar ?? (()=>void 0));
|
|
23
22
|
useEffect(()=>{
|
|
24
23
|
var _bar_current;
|
|
25
|
-
|
|
26
|
-
null == (_bar_current = bar.current) || _bar_current.addListener(onScrollbar);
|
|
24
|
+
null == (_bar_current = bar.current) || _bar_current.addListener(onScrollbarListener);
|
|
27
25
|
return ()=>{
|
|
28
26
|
var _bar_current;
|
|
29
|
-
return null == (_bar_current = bar.current) ? void 0 : _bar_current.removeListener(
|
|
27
|
+
return null == (_bar_current = bar.current) ? void 0 : _bar_current.removeListener(onScrollbarListener);
|
|
30
28
|
};
|
|
31
|
-
}, [
|
|
32
|
-
onScrollbar
|
|
33
|
-
]);
|
|
29
|
+
}, []);
|
|
34
30
|
const style2 = css`
|
|
35
31
|
.scrollbar-track.scrollbar-track-x {
|
|
36
32
|
${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""}
|
|
@@ -66,5 +62,5 @@ const Scroll = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
66
62
|
...rest,
|
|
67
63
|
children: children
|
|
68
64
|
});
|
|
69
|
-
}
|
|
65
|
+
};
|
|
70
66
|
export { Scroll, smooth_scrollbar as Scrollbar };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepsea-components",
|
|
3
|
-
"version": "5.17.
|
|
3
|
+
"version": "5.17.15",
|
|
4
4
|
"description": "格数科技自用组件库",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"hls.js": "^1.6.13",
|
|
42
42
|
"smooth-scrollbar": "^8.8.4",
|
|
43
43
|
"stable-hash": "^0.0.6",
|
|
44
|
-
"deepsea-tools": "5.43.
|
|
45
|
-
"soda-hooks": "6.16.
|
|
44
|
+
"deepsea-tools": "5.43.5",
|
|
45
|
+
"soda-hooks": "6.16.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"typescript": ">=5.8.3"
|
|
@@ -51,13 +51,12 @@
|
|
|
51
51
|
"@types/node": "^24.10.2",
|
|
52
52
|
"@types/react": ">=19.2.7",
|
|
53
53
|
"@types/react-dom": ">=19.2.3",
|
|
54
|
-
"react": ">=19.2.
|
|
55
|
-
"react-dom": ">=19.2.
|
|
54
|
+
"react": ">=19.2.3",
|
|
55
|
+
"react-dom": ">=19.2.3"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"dev": "rslib build --watch",
|
|
59
59
|
"build": "rslib build",
|
|
60
|
-
"prebuild": "bun scripts/export.ts"
|
|
61
|
-
"lint": "prettier --write ."
|
|
60
|
+
"prebuild": "bun scripts/export.ts"
|
|
62
61
|
}
|
|
63
62
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { CSSProperties,
|
|
3
|
+
import { CSSProperties, FC, MouseEvent as ReactMouseEvent, useEffect, useEffectEvent, useImperativeHandle, useRef } from "react"
|
|
4
4
|
|
|
5
5
|
import { css } from "@emotion/css"
|
|
6
6
|
import { clsx, getArray } from "deepsea-tools"
|
|
@@ -16,8 +16,8 @@ export interface AutoScrollProps extends ScrollProps {
|
|
|
16
16
|
/** 轮播元素的个数 */
|
|
17
17
|
count: number
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
|
|
19
|
+
/** 轮播元素的尺寸(垂直滚动时为高度,水平滚动时为宽度) */
|
|
20
|
+
itemSize: number
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* 轮播动画的时间,单位毫秒
|
|
@@ -43,6 +43,12 @@ export interface AutoScrollProps extends ScrollProps {
|
|
|
43
43
|
/** 容器样式 */
|
|
44
44
|
containerStyle?: CSSProperties
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* 滚动方向
|
|
48
|
+
* @default vertical
|
|
49
|
+
*/
|
|
50
|
+
direction?: "vertical" | "horizontal"
|
|
51
|
+
|
|
46
52
|
/**
|
|
47
53
|
* 在鼠标移入时是否继续播放
|
|
48
54
|
* @default false
|
|
@@ -56,30 +62,31 @@ export interface AutoScrollProps extends ScrollProps {
|
|
|
56
62
|
paused?: boolean
|
|
57
63
|
}
|
|
58
64
|
|
|
59
|
-
export const AutoScroll
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
export const AutoScroll: FC<AutoScrollProps> = ({
|
|
66
|
+
ref,
|
|
67
|
+
count,
|
|
68
|
+
itemSize,
|
|
69
|
+
animation = 1000,
|
|
70
|
+
duration = 3000,
|
|
71
|
+
onMouseEnter,
|
|
72
|
+
onMouseLeave,
|
|
73
|
+
gap = 0,
|
|
74
|
+
containerClassName,
|
|
75
|
+
containerStyle,
|
|
76
|
+
children,
|
|
77
|
+
playOnMouseEnter,
|
|
78
|
+
scrollbar,
|
|
79
|
+
paused,
|
|
80
|
+
direction = "vertical",
|
|
81
|
+
...rest
|
|
82
|
+
}) => {
|
|
83
|
+
const isVertical = direction === "vertical"
|
|
76
84
|
const bar = useRef<Scrollbar | null>(null)
|
|
77
85
|
const timeout = useRef<NodeJS.Timeout | undefined>(undefined)
|
|
78
86
|
const ele = useRef<HTMLDivElement>(null)
|
|
79
87
|
const size = useSize(ele)
|
|
80
88
|
const pausedRef = useRef(false)
|
|
81
|
-
const
|
|
82
|
-
pausedProps.current = paused
|
|
89
|
+
const getPaused = useEffectEvent(() => paused)
|
|
83
90
|
|
|
84
91
|
useImperativeHandle(ref, () => ele.current!, [])
|
|
85
92
|
useImperativeHandle(scrollbar, () => bar.current!, [])
|
|
@@ -90,35 +97,39 @@ export const AutoScroll = forwardRef<HTMLDivElement, AutoScrollProps>((props, re
|
|
|
90
97
|
|
|
91
98
|
useEffect(() => {
|
|
92
99
|
if (!size || count === 0) return
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
100
|
+
const containerSize = isVertical ? size.height : size.width
|
|
101
|
+
if (itemSize === 0 || containerSize === 0) return
|
|
102
|
+
const range = getArray(count, index => (itemSize + gap) * (index + 1) - (index === count - 1 ? gap : 0))
|
|
103
|
+
const scrollLength = range.at(-1)!
|
|
104
|
+
|
|
105
|
+
// 如果容器大小大于滚动长度,则不进行滚动
|
|
106
|
+
if (containerSize >= scrollLength) return
|
|
97
107
|
|
|
98
108
|
function scroll(target: number) {
|
|
99
109
|
clearTimeout(timeout.current)
|
|
100
110
|
timeout.current = setTimeout(() => {
|
|
101
|
-
if (pausedRef.current ||
|
|
102
|
-
bar.current?.scrollTo(0, target, animation)
|
|
111
|
+
if (pausedRef.current || getPaused()) return scroll(target)
|
|
112
|
+
bar.current?.scrollTo(isVertical ? 0 : target, isVertical ? target : 0, animation)
|
|
103
113
|
}, duration)
|
|
104
114
|
}
|
|
105
115
|
|
|
106
116
|
scroll(range[0])
|
|
107
117
|
|
|
108
118
|
function listener(status: ScrollStatus) {
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const target =
|
|
119
|
+
const offset = isVertical ? status.offset.y : status.offset.x
|
|
120
|
+
const scrollToEnd = Math.abs(offset + containerSize - scrollLength) / itemSize <= 0.05
|
|
121
|
+
const target = scrollToEnd ? 0 : range.find(item => item > offset)!
|
|
112
122
|
scroll(target)
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
bar.current?.addListener(listener)
|
|
126
|
+
|
|
116
127
|
return () => {
|
|
117
128
|
clearTimeout(timeout.current)
|
|
118
129
|
bar.current?.removeListener(listener)
|
|
119
130
|
bar.current?.scrollTo(0, 0)
|
|
120
131
|
}
|
|
121
|
-
}, [size, count,
|
|
132
|
+
}, [size, count, itemSize, gap, duration, animation, isVertical])
|
|
122
133
|
|
|
123
134
|
function onContainerMouseEnter(e: ReactMouseEvent<HTMLDivElement, MouseEvent>) {
|
|
124
135
|
if (playOnMouseEnter) return
|
|
@@ -132,24 +143,24 @@ export const AutoScroll = forwardRef<HTMLDivElement, AutoScrollProps>((props, re
|
|
|
132
143
|
onMouseLeave?.(e)
|
|
133
144
|
}
|
|
134
145
|
|
|
146
|
+
const containerStyle2 = css`
|
|
147
|
+
display: flex;
|
|
148
|
+
flex-direction: var(--flex-direction, column);
|
|
149
|
+
gap: var(--gap, 0);
|
|
150
|
+
|
|
151
|
+
& > * {
|
|
152
|
+
flex: none;
|
|
153
|
+
}
|
|
154
|
+
`
|
|
155
|
+
|
|
135
156
|
return (
|
|
136
157
|
<Scroll ref={ele} scrollbar={bar} onMouseEnter={onContainerMouseEnter} onMouseLeave={onContainerMouseLeave} {...rest}>
|
|
137
158
|
<div
|
|
138
|
-
className={clsx(
|
|
139
|
-
|
|
140
|
-
display: flex;
|
|
141
|
-
flex-direction: column;
|
|
142
|
-
gap: var(--gap, 0);
|
|
143
|
-
& > * {
|
|
144
|
-
flex: none;
|
|
145
|
-
}
|
|
146
|
-
`,
|
|
147
|
-
containerClassName,
|
|
148
|
-
)}
|
|
149
|
-
style={transformCSSVariable({ gap: px(gap) }, containerStyle)}
|
|
159
|
+
className={clsx(containerStyle2, containerClassName)}
|
|
160
|
+
style={transformCSSVariable({ gap: px(gap), flexDirection: isVertical ? "column" : "row" }, containerStyle)}
|
|
150
161
|
>
|
|
151
162
|
{children}
|
|
152
163
|
</div>
|
|
153
164
|
</Scroll>
|
|
154
165
|
)
|
|
155
|
-
}
|
|
166
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentProps, CSSProperties, FC, ForwardedRef, useEffect, useEffectEvent, useImperativeHandle, useLayoutEffect, useRef } from "react"
|
|
4
4
|
|
|
5
5
|
import { css } from "@emotion/css"
|
|
6
6
|
import { clsx } from "deepsea-tools"
|
|
@@ -24,7 +24,7 @@ export interface ScrollOptions extends Partial<ScrollbarOptions> {
|
|
|
24
24
|
trackColor?: CSSProperties["backgroundColor"]
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export interface ScrollProps extends
|
|
27
|
+
export interface ScrollProps extends ComponentProps<"div"> {
|
|
28
28
|
/** 滚动的配置 */
|
|
29
29
|
options?: ScrollOptions
|
|
30
30
|
/** 滚动条实例 */
|
|
@@ -33,9 +33,16 @@ export interface ScrollProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
33
33
|
onScrollbar?: ScrollListener
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export const Scroll
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
export const Scroll: FC<ScrollProps> = ({
|
|
37
|
+
ref,
|
|
38
|
+
children,
|
|
39
|
+
options: { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = {},
|
|
40
|
+
className,
|
|
41
|
+
scrollbar,
|
|
42
|
+
onScrollbar,
|
|
43
|
+
style,
|
|
44
|
+
...rest
|
|
45
|
+
}) => {
|
|
39
46
|
const ele = useRef<HTMLDivElement>(null)
|
|
40
47
|
const bar = useRef<Scrollbar | null>(null)
|
|
41
48
|
|
|
@@ -48,11 +55,12 @@ export const Scroll = forwardRef<HTMLDivElement, ScrollProps>((props, ref) => {
|
|
|
48
55
|
|
|
49
56
|
useImperativeHandle(scrollbar, () => bar.current!, [])
|
|
50
57
|
|
|
58
|
+
const onScrollbarListener = useEffectEvent(onScrollbar ?? (() => void 0))
|
|
59
|
+
|
|
51
60
|
useEffect(() => {
|
|
52
|
-
|
|
53
|
-
bar.current?.
|
|
54
|
-
|
|
55
|
-
}, [onScrollbar])
|
|
61
|
+
bar.current?.addListener(onScrollbarListener)
|
|
62
|
+
return () => bar.current?.removeListener(onScrollbarListener)
|
|
63
|
+
}, [])
|
|
56
64
|
|
|
57
65
|
const style2 = css`
|
|
58
66
|
.scrollbar-track.scrollbar-track-x {
|
|
@@ -96,4 +104,4 @@ export const Scroll = forwardRef<HTMLDivElement, ScrollProps>((props, ref) => {
|
|
|
96
104
|
{children}
|
|
97
105
|
</div>
|
|
98
106
|
)
|
|
99
|
-
}
|
|
107
|
+
}
|