deepsea-components 5.17.12 → 5.17.14

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.
@@ -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 = /*#__PURE__*/ (0, external_react_namespaceObject.forwardRef)((props, ref)=>{
38
- const { count, itemHeight, animation = 1000, duration = 3000, onMouseEnter, onMouseLeave, gap = 0, containerClassName, containerStyle, children, playOnMouseEnter, scrollbar, paused, ...rest } = props;
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 pausedProps = (0, external_react_namespaceObject.useRef)(paused);
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 { height } = size;
57
- const range = (0, external_deepsea_tools_namespaceObject.getArray)(count, (index)=>(itemHeight + gap) * (index + 1) - (index === count - 1 ? gap : 0));
58
- const scrollHeight = range[range.length - 1];
59
- if (height >= scrollHeight) return;
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 || pausedProps.current) return scroll(target);
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 { y } = status.offset;
71
- const scrollToBottom = Math.abs(y + height - scrollHeight) / itemHeight <= 0.05;
72
- const target = scrollToBottom ? 0 : range.find((item)=>item > y);
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
- itemHeight,
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)((0, css_namespaceObject.css)`
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
- itemHeight: number;
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: import("react").ForwardRefExoticComponent<AutoScrollProps & import("react").RefAttributes<HTMLDivElement>>;
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 { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
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 = /*#__PURE__*/ forwardRef((props, ref)=>{
10
- const { count, itemHeight, animation = 1000, duration = 3000, onMouseEnter, onMouseLeave, gap = 0, containerClassName, containerStyle, children, playOnMouseEnter, scrollbar, paused, ...rest } = props;
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 pausedProps = useRef(paused);
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 { height } = size;
29
- const range = getArray(count, (index)=>(itemHeight + gap) * (index + 1) - (index === count - 1 ? gap : 0));
30
- const scrollHeight = range[range.length - 1];
31
- if (height >= scrollHeight) return;
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 || pausedProps.current) return scroll(target);
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 { y } = status.offset;
43
- const scrollToBottom = Math.abs(y + height - scrollHeight) / itemHeight <= 0.05;
44
- const target = scrollToBottom ? 0 : range.find((item)=>item > y);
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
- itemHeight,
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(css`
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 };
@@ -31,7 +31,7 @@ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
31
31
  const external_react_namespaceObject = require("react");
32
32
  const css_namespaceObject = require("@emotion/css");
33
33
  const external_deepsea_tools_namespaceObject = require("deepsea-tools");
34
- const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, container: containerClassName, mirror: mirrorClassName } = {}, children, direction, period, reverse, pauseOnHover = true, gap = 0, ...rest })=>{
34
+ const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, container: containerClassName, mirror: mirrorClassName } = {}, children, direction, period, reverse, pauseOnHover = true, paused, gap = 0, ...rest })=>{
35
35
  const wrapper = (0, external_react_namespaceObject.useRef)(null);
36
36
  const container = (0, external_react_namespaceObject.useRef)(null);
37
37
  const [swiper, setSwiper] = (0, external_react_namespaceObject.useState)(false);
@@ -65,6 +65,14 @@ const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, contain
65
65
  observer.observe(wrapperEle);
66
66
  observer.observe(containerEle);
67
67
  }, []);
68
+ const style = (0, css_namespaceObject.css)`
69
+ display: flex;
70
+ flex-direction: ${flexDirection};
71
+ gap: ${gap}px;
72
+ ${"vertical" === direction ? "overflow-y: hidden;" : "overflow-x: hidden;"}
73
+ ${pauseOnHover ? "&:hover > * { animation-play-state: paused; }" : ""}
74
+ ${paused ? "& > * { animation-play-state: paused; }" : ""}
75
+ `;
68
76
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
69
77
  ref: wrapper,
70
78
  className: (0, external_deepsea_tools_namespaceObject.clsx)((0, css_namespaceObject.css)`
@@ -100,12 +108,7 @@ const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, contain
100
108
  transform: translateY(calc(100% + ${gap}px));
101
109
  }
102
110
  }
103
- `, (0, css_namespaceObject.css)`
104
- display: flex;
105
- flex-direction: ${flexDirection};
106
- gap: ${gap}px;
107
- ${"vertical" === direction ? "overflow-y: hidden;" : "overflow-x: hidden;"} ${pauseOnHover ? "&:hover > * { animation-play-state: paused; }" : ""}
108
- `, className, rootClassName),
111
+ `, style, rootClassName, className),
109
112
  ...rest,
110
113
  children: [
111
114
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
@@ -10,6 +10,7 @@ export interface LoopSwiperProps extends ComponentProps<"div"> {
10
10
  reverse?: boolean;
11
11
  period: number;
12
12
  pauseOnHover?: boolean;
13
+ paused?: boolean;
13
14
  gap?: number;
14
15
  }
15
16
  /** 循环播放组件 */
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useImperativeHandle, useRef, useState } from "react";
4
4
  import { css } from "@emotion/css";
5
5
  import { clsx } from "deepsea-tools";
6
- const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, container: containerClassName, mirror: mirrorClassName } = {}, children, direction, period, reverse, pauseOnHover = true, gap = 0, ...rest })=>{
6
+ const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, container: containerClassName, mirror: mirrorClassName } = {}, children, direction, period, reverse, pauseOnHover = true, paused, gap = 0, ...rest })=>{
7
7
  const wrapper = useRef(null);
8
8
  const container = useRef(null);
9
9
  const [swiper, setSwiper] = useState(false);
@@ -37,6 +37,14 @@ const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, contain
37
37
  observer.observe(wrapperEle);
38
38
  observer.observe(containerEle);
39
39
  }, []);
40
+ const style = css`
41
+ display: flex;
42
+ flex-direction: ${flexDirection};
43
+ gap: ${gap}px;
44
+ ${"vertical" === direction ? "overflow-y: hidden;" : "overflow-x: hidden;"}
45
+ ${pauseOnHover ? "&:hover > * { animation-play-state: paused; }" : ""}
46
+ ${paused ? "& > * { animation-play-state: paused; }" : ""}
47
+ `;
40
48
  return /*#__PURE__*/ jsxs("div", {
41
49
  ref: wrapper,
42
50
  className: clsx(css`
@@ -72,12 +80,7 @@ const LoopSwiper = ({ ref, className, classNames: { root: rootClassName, contain
72
80
  transform: translateY(calc(100% + ${gap}px));
73
81
  }
74
82
  }
75
- `, css`
76
- display: flex;
77
- flex-direction: ${flexDirection};
78
- gap: ${gap}px;
79
- ${"vertical" === direction ? "overflow-y: hidden;" : "overflow-x: hidden;"} ${pauseOnHover ? "&:hover > * { animation-play-state: paused; }" : ""}
80
- `, className, rootClassName),
83
+ `, style, rootClassName, className),
81
84
  ...rest,
82
85
  children: [
83
86
  /*#__PURE__*/ jsx("div", {
@@ -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 = /*#__PURE__*/ (0, react__WEBPACK_IMPORTED_MODULE_1__.forwardRef)((props, ref)=>{
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,33 +99,41 @@ 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
- if (!onScrollbar) return;
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(onScrollbar);
108
+ return null == (_bar_current = bar.current) ? void 0 : _bar_current.removeListener(onScrollbarListener);
111
109
  };
112
- }, [
113
- onScrollbar
114
- ]);
110
+ }, []);
111
+ const style2 = (0, _emotion_css__WEBPACK_IMPORTED_MODULE_2__.css)`
112
+ .scrollbar-track.scrollbar-track-x {
113
+ ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""}
114
+ ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
115
+ }
116
+
117
+ .scrollbar-thumb.scrollbar-thumb-x {
118
+ ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""}
119
+ ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""}
120
+ ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
121
+ }
122
+
123
+ .scrollbar-track.scrollbar-track-y {
124
+ ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""}
125
+ ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
126
+ }
127
+
128
+ .scrollbar-thumb.scrollbar-thumb-y {
129
+ ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""}
130
+ ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""}
131
+ ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
132
+ }
133
+ `;
115
134
  return /*#__PURE__*/ (0, react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
116
135
  ref: ele,
117
- className: (0, deepsea_tools__WEBPACK_IMPORTED_MODULE_3__.clsx)((0, _emotion_css__WEBPACK_IMPORTED_MODULE_2__.css)`
118
- .scrollbar-track.scrollbar-track-x {
119
- ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""} ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
120
- }
121
- .scrollbar-thumb.scrollbar-thumb-x {
122
- ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""} ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""} ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
123
- }
124
- .scrollbar-track.scrollbar-track-y {
125
- ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""} ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
126
- }
127
- .scrollbar-thumb.scrollbar-thumb-y {
128
- ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""} ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""} ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
129
- }
130
- `, className),
136
+ className: (0, deepsea_tools__WEBPACK_IMPORTED_MODULE_3__.clsx)(style2, className),
131
137
  style: (0, _utils__WEBPACK_IMPORTED_MODULE_5__.transformCSSVariable)({
132
138
  thumbWidth: (0, _utils__WEBPACK_IMPORTED_MODULE_5__.px)(thumbWidth),
133
139
  thumbRadius: (0, _utils__WEBPACK_IMPORTED_MODULE_5__.px)(thumbRadius),
@@ -137,7 +143,7 @@ var __webpack_exports__ = {};
137
143
  ...rest,
138
144
  children: children
139
145
  });
140
- });
146
+ };
141
147
  })();
142
148
  exports.Scroll = __webpack_exports__.Scroll;
143
149
  exports.Scrollbar = __webpack_exports__.Scrollbar;
@@ -1,4 +1,4 @@
1
- import { CSSProperties, ForwardedRef, HTMLAttributes } from "react";
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 HTMLAttributes<HTMLDivElement> {
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: import("react").ForwardRefExoticComponent<ScrollProps & import("react").RefAttributes<HTMLDivElement>>;
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 { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef } from "react";
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 = /*#__PURE__*/ forwardRef((props, ref)=>{
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,33 +18,41 @@ 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
- if (!onScrollbar) return;
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(onScrollbar);
27
+ return null == (_bar_current = bar.current) ? void 0 : _bar_current.removeListener(onScrollbarListener);
30
28
  };
31
- }, [
32
- onScrollbar
33
- ]);
29
+ }, []);
30
+ const style2 = css`
31
+ .scrollbar-track.scrollbar-track-x {
32
+ ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""}
33
+ ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
34
+ }
35
+
36
+ .scrollbar-thumb.scrollbar-thumb-x {
37
+ ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""}
38
+ ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""}
39
+ ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
40
+ }
41
+
42
+ .scrollbar-track.scrollbar-track-y {
43
+ ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""}
44
+ ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
45
+ }
46
+
47
+ .scrollbar-thumb.scrollbar-thumb-y {
48
+ ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""}
49
+ ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""}
50
+ ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
51
+ }
52
+ `;
34
53
  return /*#__PURE__*/ jsx("div", {
35
54
  ref: ele,
36
- className: clsx(css`
37
- .scrollbar-track.scrollbar-track-x {
38
- ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""} ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
39
- }
40
- .scrollbar-thumb.scrollbar-thumb-x {
41
- ${void 0 !== thumbWidth ? "height: var(--thumb-width);" : ""} ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""} ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
42
- }
43
- .scrollbar-track.scrollbar-track-y {
44
- ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""} ${void 0 !== trackColor ? "background-color: var(--track-color);" : ""}
45
- }
46
- .scrollbar-thumb.scrollbar-thumb-y {
47
- ${void 0 !== thumbWidth ? "width: var(--thumb-width);" : ""} ${void 0 !== thumbRadius ? "border-radius: var(--thumb-radius);" : ""} ${void 0 !== thumbColor ? "background-color: var(--thumb-color);" : ""}
48
- }
49
- `, className),
55
+ className: clsx(style2, className),
50
56
  style: transformCSSVariable({
51
57
  thumbWidth: px(thumbWidth),
52
58
  thumbRadius: px(thumbRadius),
@@ -56,5 +62,5 @@ const Scroll = /*#__PURE__*/ forwardRef((props, ref)=>{
56
62
  ...rest,
57
63
  children: children
58
64
  });
59
- });
65
+ };
60
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.12",
3
+ "version": "5.17.14",
4
4
  "description": "格数科技自用组件库",
5
5
  "type": "module",
6
6
  "exports": {
@@ -41,14 +41,14 @@
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.3",
45
- "soda-hooks": "6.16.2"
44
+ "deepsea-tools": "5.43.4",
45
+ "soda-hooks": "6.16.3"
46
46
  },
47
47
  "devDependencies": {
48
48
  "typescript": ">=5.8.3"
49
49
  },
50
50
  "peerDependencies": {
51
- "@types/node": ">=24.10.1",
51
+ "@types/node": "^24.10.2",
52
52
  "@types/react": ">=19.2.7",
53
53
  "@types/react-dom": ">=19.2.3",
54
54
  "react": ">=19.2.1",
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
 
3
- import { CSSProperties, forwardRef, MouseEvent as ReactMouseEvent, useEffect, useImperativeHandle, useRef } from "react"
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
- itemHeight: number
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 = forwardRef<HTMLDivElement, AutoScrollProps>((props, ref) => {
60
- const {
61
- count,
62
- itemHeight,
63
- animation = 1000,
64
- duration = 3000,
65
- onMouseEnter,
66
- onMouseLeave,
67
- gap = 0,
68
- containerClassName,
69
- containerStyle,
70
- children,
71
- playOnMouseEnter,
72
- scrollbar,
73
- paused,
74
- ...rest
75
- } = props
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 pausedProps = useRef(paused)
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 { height } = size
94
- const range = getArray(count, index => (itemHeight + gap) * (index + 1) - (index === count - 1 ? gap : 0))
95
- const scrollHeight = range[range.length - 1]
96
- if (height >= scrollHeight) return
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 || pausedProps.current) return scroll(target)
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 { y } = status.offset
110
- const scrollToBottom = Math.abs(y + height - scrollHeight) / itemHeight <= 0.05
111
- const target = scrollToBottom ? 0 : range.find(item => item > y)!
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, itemHeight, gap, duration, animation])
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
- css`
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
+ }
@@ -17,6 +17,7 @@ export interface LoopSwiperProps extends ComponentProps<"div"> {
17
17
  reverse?: boolean
18
18
  period: number
19
19
  pauseOnHover?: boolean
20
+ paused?: boolean
20
21
  gap?: number
21
22
  }
22
23
 
@@ -30,6 +31,7 @@ export const LoopSwiper: FC<LoopSwiperProps> = ({
30
31
  period,
31
32
  reverse,
32
33
  pauseOnHover = true,
34
+ paused,
33
35
  gap = 0,
34
36
  ...rest
35
37
  }) => {
@@ -82,6 +84,15 @@ export const LoopSwiper: FC<LoopSwiperProps> = ({
82
84
  observer.observe(containerEle)
83
85
  }, [])
84
86
 
87
+ const style = css`
88
+ display: flex;
89
+ flex-direction: ${flexDirection};
90
+ gap: ${gap}px;
91
+ ${direction === "vertical" ? "overflow-y: hidden;" : "overflow-x: hidden;"}
92
+ ${pauseOnHover ? `&:hover > * { animation-play-state: paused; }` : ""}
93
+ ${paused ? "& > * { animation-play-state: paused; }" : ""}
94
+ `
95
+
85
96
  return (
86
97
  <div
87
98
  ref={wrapper}
@@ -120,16 +131,9 @@ export const LoopSwiper: FC<LoopSwiperProps> = ({
120
131
  }
121
132
  }
122
133
  `,
123
- css`
124
- display: flex;
125
- flex-direction: ${flexDirection};
126
- gap: ${gap}px;
127
- ${direction === "vertical" ? "overflow-y: hidden;" : "overflow-x: hidden;"} ${pauseOnHover
128
- ? `&:hover > * { animation-play-state: paused; }`
129
- : ""}
130
- `,
131
- className,
134
+ style,
132
135
  rootClassName,
136
+ className,
133
137
  )}
134
138
  {...rest}
135
139
  >
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
 
3
- import { CSSProperties, ForwardedRef, forwardRef, HTMLAttributes, useEffect, useImperativeHandle, useLayoutEffect, useRef } from "react"
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 HTMLAttributes<HTMLDivElement> {
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 = forwardRef<HTMLDivElement, ScrollProps>((props, ref) => {
37
- const { children, options, className, style, scrollbar, onScrollbar, ...rest } = props
38
- const { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = options || {}
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,40 +55,41 @@ 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
- if (!onScrollbar) return
53
- bar.current?.addListener(onScrollbar)
54
- return () => bar.current?.removeListener(onScrollbar)
55
- }, [onScrollbar])
61
+ bar.current?.addListener(onScrollbarListener)
62
+ return () => bar.current?.removeListener(onScrollbarListener)
63
+ }, [])
64
+
65
+ const style2 = css`
66
+ .scrollbar-track.scrollbar-track-x {
67
+ ${thumbWidth !== undefined ? "height: var(--thumb-width);" : ""}
68
+ ${trackColor !== undefined ? "background-color: var(--track-color);" : ""}
69
+ }
70
+
71
+ .scrollbar-thumb.scrollbar-thumb-x {
72
+ ${thumbWidth !== undefined ? "height: var(--thumb-width);" : ""}
73
+ ${thumbRadius !== undefined ? "border-radius: var(--thumb-radius);" : ""}
74
+ ${thumbColor !== undefined ? "background-color: var(--thumb-color);" : ""}
75
+ }
76
+
77
+ .scrollbar-track.scrollbar-track-y {
78
+ ${thumbWidth !== undefined ? "width: var(--thumb-width);" : ""}
79
+ ${trackColor !== undefined ? "background-color: var(--track-color);" : ""}
80
+ }
81
+
82
+ .scrollbar-thumb.scrollbar-thumb-y {
83
+ ${thumbWidth !== undefined ? "width: var(--thumb-width);" : ""}
84
+ ${thumbRadius !== undefined ? "border-radius: var(--thumb-radius);" : ""}
85
+ ${thumbColor !== undefined ? "background-color: var(--thumb-color);" : ""}
86
+ }
87
+ `
56
88
 
57
89
  return (
58
90
  <div
59
91
  ref={ele}
60
- className={clsx(
61
- css`
62
- .scrollbar-track.scrollbar-track-x {
63
- ${thumbWidth !== undefined ? "height: var(--thumb-width);" : ""} ${trackColor !== undefined
64
- ? "background-color: var(--track-color);"
65
- : ""}
66
- }
67
- .scrollbar-thumb.scrollbar-thumb-x {
68
- ${thumbWidth !== undefined ? "height: var(--thumb-width);" : ""} ${thumbRadius !== undefined
69
- ? "border-radius: var(--thumb-radius);"
70
- : ""} ${thumbColor !== undefined ? "background-color: var(--thumb-color);" : ""}
71
- }
72
- .scrollbar-track.scrollbar-track-y {
73
- ${thumbWidth !== undefined ? "width: var(--thumb-width);" : ""} ${trackColor !== undefined
74
- ? "background-color: var(--track-color);"
75
- : ""}
76
- }
77
- .scrollbar-thumb.scrollbar-thumb-y {
78
- ${thumbWidth !== undefined ? "width: var(--thumb-width);" : ""} ${thumbRadius !== undefined
79
- ? "border-radius: var(--thumb-radius);"
80
- : ""} ${thumbColor !== undefined ? "background-color: var(--thumb-color);" : ""}
81
- }
82
- `,
83
- className,
84
- )}
92
+ className={clsx(style2, className)}
85
93
  style={transformCSSVariable(
86
94
  {
87
95
  thumbWidth: px(thumbWidth),
@@ -96,4 +104,4 @@ export const Scroll = forwardRef<HTMLDivElement, ScrollProps>((props, ref) => {
96
104
  {children}
97
105
  </div>
98
106
  )
99
- })
107
+ }