pixuireactcomponents 1.5.63 → 1.5.64

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixuireactcomponents",
3
- "version": "1.5.63",
3
+ "version": "1.5.64",
4
4
  "description": "pixui react components",
5
5
  "main": "index.js",
6
6
  "sideEffects": false,
@@ -1,4 +1,4 @@
1
- import preact, { CSSProperties, h, Component } from 'preact';
1
+ import preact, { CSSProperties, h } from 'preact';
2
2
  export interface dropDownOption {
3
3
  value: string;
4
4
  label?: h.JSX.Element;
@@ -15,21 +15,4 @@ export interface DropDownProps {
15
15
  onChange?: (value: string) => void;
16
16
  onSpread?: (spread: boolean) => void;
17
17
  }
18
- interface DropDownState {
19
- spread: boolean;
20
- }
21
- export declare class DropDown extends Component<DropDownProps, DropDownState> {
22
- private dropdownRef;
23
- private dropdownContentRef;
24
- private handleClickOutsideFn;
25
- constructor(props: DropDownProps);
26
- componentDidUpdate(_prevProps: DropDownProps, prevState: DropDownState): void;
27
- componentWillUnmount(): void;
28
- private updateClickOutsideListener;
29
- private removeClickOutsideListener;
30
- private getElementStyleOrClass;
31
- private handleOverlayClick;
32
- private optionRender;
33
- render(): preact.JSX.Element;
34
- }
35
- export {};
18
+ export declare const DropDown: (props: DropDownProps) => preact.JSX.Element;
@@ -1,21 +1,3 @@
1
- // import { useEffect, useRef, useState } from 'preact/hooks';
2
- // import preact, { CSSProperties, h, isValidElement } from 'preact';
3
- // import { cloneElement } from 'preact';
4
- var __extends = (this && this.__extends) || (function () {
5
- var extendStatics = function (d, b) {
6
- extendStatics = Object.setPrototypeOf ||
7
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
8
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
9
- return extendStatics(d, b);
10
- };
11
- return function (d, b) {
12
- if (typeof b !== "function" && b !== null)
13
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
14
- extendStatics(d, b);
15
- function __() { this.constructor = d; }
16
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
17
- };
18
- })();
19
1
  var __assign = (this && this.__assign) || function () {
20
2
  __assign = Object.assign || function(t) {
21
3
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -27,128 +9,8 @@ var __assign = (this && this.__assign) || function () {
27
9
  };
28
10
  return __assign.apply(this, arguments);
29
11
  };
30
- // const defaultDropDownStyle: CSSProperties = {
31
- // margin: 0,
32
- // padding: '4px 0',
33
- // backgroundColor: '#fff',
34
- // borderRadius: '5px',
35
- // border: '2px solid rgba(5, 5, 5, 0.06)',
36
- // boxShadow:'0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05)'
37
- // }
38
- // export interface dropDownOption {
39
- // value: string; // item唯一标识
40
- // label?: h.JSX.Element; // item标签元素
41
- // }
42
- // export interface dropdownElement {
43
- // dropdownBg?: string | CSSProperties; // 下拉框样式
44
- // }
45
- // export interface DropDownProps {
46
- // rootId?: string;
47
- // rootClassName?: string;
48
- // options: dropDownOption[];
49
- // element?: dropdownElement; // 自定义元素样式
50
- // children?: h.JSX.Element;
51
- // onChange?: (value: string) => void;
52
- // onSpread?: (spread: boolean) => void;
53
- // // compRef?: any;
54
- // }
55
- // export const DropDown = (props: DropDownProps) => {
56
- // const {
57
- // rootId,
58
- // rootClassName,
59
- // options,
60
- // element,
61
- // children,
62
- // onChange,
63
- // onSpread,
64
- // // compRef
65
- // } = props;
66
- // const getElementStyleOrClass = () =>{
67
- // if(element == undefined){
68
- // return {
69
- // dropdownBg: defaultDropDownStyle
70
- // }
71
- // } else {
72
- // return element;
73
- // }
74
- // }
75
- // const elementStyleOrClass = getElementStyleOrClass();
76
- // const [spread, setSpread] = useState(false);
77
- // const dropdownRef = useRef<HTMLDivElement>(null);
78
- // const dropdownContentRef = useRef<HTMLDivElement>(null);
79
- // useEffect(() => {
80
- // onSpread && onSpread(spread);
81
- // }, [spread]);
82
- // useEffect(() => {
83
- // const handleClickOutside = (event) => {
84
- // // console.log('handleClickOutside, ', event.clientX, event.clientY)
85
- // if (dropdownRef.current && dropdownContentRef.current) {
86
- // const dropDownRect = dropdownRef.current.getBoundingClientRect();
87
- // const contentRect = dropdownContentRef.current.getBoundingClientRect();
88
- // // console.log('dropDownRect', dropDownRect, 'isOutside', event.clientX < dropDownRect.left, 'isOutside', event.clientX > dropDownRect.right, 'isOutside', event.clientY < dropDownRect.top, 'isOutside', event.clientY > dropDownRect.bottom)
89
- // // console.log('contentRect', contentRect, 'isOutside', event.clientX < contentRect.left, 'isOutside', event.clientX > contentRect.right, 'isOutside', event.clientY < contentRect.top, 'isOutside', event.clientY > contentRect.bottom)
90
- // const isOutsideDropdown =
91
- // event.clientX < dropDownRect.left ||
92
- // event.clientX > dropDownRect.right ||
93
- // event.clientY < dropDownRect.top ||
94
- // event.clientY > dropDownRect.bottom;
95
- // const isOutsideContent =
96
- // event.clientX < contentRect.left ||
97
- // event.clientX > contentRect.right ||
98
- // event.clientY < contentRect.top ||
99
- // event.clientY > contentRect.bottom;
100
- // if(isOutsideDropdown && isOutsideContent) {
101
- // setSpread(false);
102
- // }
103
- // }
104
- // };
105
- // if (spread) {
106
- // // console.log('开始监听mousedown', spread)
107
- // document.body.addEventListener('mousedown', handleClickOutside);
108
- // }
109
- // return () => {
110
- // document.body.removeEventListener('mousedown', handleClickOutside);
111
- // };
112
- // }, [spread]);
113
- // const handleOverlayClick = (event) => {
114
- // // console.log("handleOverLayClick")
115
- // event.stopPropagation();
116
- // setSpread(!spread);
117
- // };
118
- // const overlayRender = isValidElement(children) ? cloneElement(children, { onClick: handleOverlayClick}) : children
119
- // const optionRender = (option: dropDownOption) => {
120
- // if(!isValidElement(option.label)){
121
- // return option.label;
122
- // }
123
- // const element = option.label as h.JSX.Element & { props: { onClick?: (event: Event) => void } }
124
- // const originalClick = element.props.onClick;
125
- // const newOnClick = (event) => {
126
- // // console.log('new onClick');
127
- // if(originalClick){
128
- // originalClick(event);
129
- // }
130
- // onChange && onChange(option.value);
131
- // setSpread(false)
132
- // }
133
- // return cloneElement(option.label, { onClick: newOnClick });
134
- // }
135
- // return (
136
- // <div style={{ flexDirection: 'column', flexShrink: 0 }} className={rootClassName} id={rootId} ref={dropdownRef}>
137
- // {overlayRender}
138
- // {spread && (
139
- // //在下方展开
140
- // <div ref={dropdownContentRef}
141
- // className={typeof elementStyleOrClass.dropdownBg === 'string' ? elementStyleOrClass.dropdownBg : ''}
142
- // style={{ flexDirection: 'column', overflow: 'scroll', ...( typeof elementStyleOrClass.dropdownBg === 'object' ? elementStyleOrClass.dropdownBg : undefined)}}>
143
- // {options.map((option, index) => {
144
- // return (<div>{optionRender(option)}</div>);
145
- // })}
146
- // </div>
147
- // )}
148
- // </div>
149
- // );
150
- // }
151
- import { h, isValidElement, Component, createRef } from 'preact';
12
+ import { useEffect, useRef, useState } from 'preact/hooks';
13
+ import { h, isValidElement } from 'preact';
152
14
  import { cloneElement } from 'preact';
153
15
  var defaultDropDownStyle = {
154
16
  margin: 0,
@@ -158,98 +20,81 @@ var defaultDropDownStyle = {
158
20
  border: '2px solid rgba(5, 5, 5, 0.06)',
159
21
  boxShadow: '0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05)'
160
22
  };
161
- var DropDown = /** @class */ (function (_super) {
162
- __extends(DropDown, _super);
163
- function DropDown(props) {
164
- var _this = _super.call(this, props) || this;
165
- _this.dropdownRef = createRef();
166
- _this.dropdownContentRef = createRef();
167
- _this.handleClickOutsideFn = null;
168
- _this.handleOverlayClick = function (event) {
169
- event.stopPropagation();
170
- _this.setState({ spread: !_this.state.spread });
171
- };
172
- _this.optionRender = function (option) {
173
- if (!isValidElement(option.label)) {
174
- return option.label;
175
- }
176
- var element = option.label;
177
- var originalClick = element.props.onClick;
178
- var newOnClick = function (event) {
179
- if (originalClick) {
180
- originalClick(event);
181
- }
182
- _this.props.onChange && _this.props.onChange(option.value);
183
- _this.setState({ spread: false });
23
+ export var DropDown = function (props) {
24
+ var rootId = props.rootId, rootClassName = props.rootClassName, options = props.options, element = props.element, children = props.children, onChange = props.onChange, onSpread = props.onSpread;
25
+ var getElementStyleOrClass = function () {
26
+ if (element == undefined) {
27
+ return {
28
+ dropdownBg: defaultDropDownStyle
184
29
  };
185
- return cloneElement(option.label, { onClick: newOnClick });
186
- };
187
- _this.state = { spread: false };
188
- return _this;
189
- }
190
- DropDown.prototype.componentDidUpdate = function (_prevProps, prevState) {
191
- if (prevState.spread !== this.state.spread) {
192
- var onSpread = this.props.onSpread;
193
- onSpread && onSpread(this.state.spread);
194
- this.updateClickOutsideListener();
195
30
  }
196
- };
197
- DropDown.prototype.componentWillUnmount = function () {
198
- this.removeClickOutsideListener();
199
- };
200
- DropDown.prototype.updateClickOutsideListener = function () {
201
- var _this = this;
202
- this.removeClickOutsideListener();
203
- if (this.state.spread) {
204
- this.handleClickOutsideFn = function (event) {
205
- if (_this.dropdownRef.current && _this.dropdownContentRef.current) {
206
- var dropDownRect = _this.dropdownRef.current.getBoundingClientRect();
207
- var contentRect = _this.dropdownContentRef.current.getBoundingClientRect();
208
- var isOutsideDropdown = event.clientX < dropDownRect.left ||
209
- event.clientX > dropDownRect.right ||
210
- event.clientY < dropDownRect.top ||
211
- event.clientY > dropDownRect.bottom;
212
- var isOutsideContent = event.clientX < contentRect.left ||
213
- event.clientX > contentRect.right ||
214
- event.clientY < contentRect.top ||
215
- event.clientY > contentRect.bottom;
216
- if (isOutsideDropdown && isOutsideContent) {
217
- _this.setState({ spread: false });
218
- }
219
- }
220
- };
221
- document.body.addEventListener('mousedown', this.handleClickOutsideFn);
31
+ else {
32
+ return element;
222
33
  }
223
34
  };
224
- DropDown.prototype.removeClickOutsideListener = function () {
225
- if (this.handleClickOutsideFn) {
226
- document.body.removeEventListener('mousedown', this.handleClickOutsideFn);
227
- this.handleClickOutsideFn = null;
35
+ var elementStyleOrClass = getElementStyleOrClass();
36
+ var _a = useState(false), spread = _a[0], setSpread = _a[1];
37
+ var dropdownRef = useRef(null);
38
+ var dropdownContentRef = useRef(null);
39
+ useEffect(function () {
40
+ onSpread && onSpread(spread);
41
+ }, [spread]);
42
+ useEffect(function () {
43
+ var handleClickOutside = function (event) {
44
+ // console.log('handleClickOutside, ', event.clientX, event.clientY)
45
+ if (dropdownRef.current && dropdownContentRef.current) {
46
+ var dropDownRect = dropdownRef.current.getBoundingClientRect();
47
+ var contentRect = dropdownContentRef.current.getBoundingClientRect();
48
+ // console.log('dropDownRect', dropDownRect, 'isOutside', event.clientX < dropDownRect.left, 'isOutside', event.clientX > dropDownRect.right, 'isOutside', event.clientY < dropDownRect.top, 'isOutside', event.clientY > dropDownRect.bottom)
49
+ // console.log('contentRect', contentRect, 'isOutside', event.clientX < contentRect.left, 'isOutside', event.clientX > contentRect.right, 'isOutside', event.clientY < contentRect.top, 'isOutside', event.clientY > contentRect.bottom)
50
+ var isOutsideDropdown = event.clientX < dropDownRect.left ||
51
+ event.clientX > dropDownRect.right ||
52
+ event.clientY < dropDownRect.top ||
53
+ event.clientY > dropDownRect.bottom;
54
+ var isOutsideContent = event.clientX < contentRect.left ||
55
+ event.clientX > contentRect.right ||
56
+ event.clientY < contentRect.top ||
57
+ event.clientY > contentRect.bottom;
58
+ if (isOutsideDropdown && isOutsideContent) {
59
+ setSpread(false);
60
+ }
61
+ }
62
+ };
63
+ if (spread) {
64
+ // console.log('开始监听mousedown', spread)
65
+ document.body.addEventListener('mousedown', handleClickOutside);
228
66
  }
67
+ return function () {
68
+ document.body.removeEventListener('mousedown', handleClickOutside);
69
+ };
70
+ }, [spread]);
71
+ var handleOverlayClick = function (event) {
72
+ // console.log("handleOverLayClick")
73
+ event.stopPropagation();
74
+ setSpread(!spread);
229
75
  };
230
- DropDown.prototype.getElementStyleOrClass = function () {
231
- var element = this.props.element;
232
- if (element == undefined) {
233
- return { dropdownBg: defaultDropDownStyle };
234
- }
235
- else {
236
- return element;
76
+ var overlayRender = isValidElement(children) ? cloneElement(children, { onClick: handleOverlayClick }) : children;
77
+ var optionRender = function (option) {
78
+ if (!isValidElement(option.label)) {
79
+ return option.label;
237
80
  }
81
+ var element = option.label;
82
+ var originalClick = element.props.onClick;
83
+ var newOnClick = function (event) {
84
+ // console.log('new onClick');
85
+ if (originalClick) {
86
+ originalClick(event);
87
+ }
88
+ onChange && onChange(option.value);
89
+ setSpread(false);
90
+ };
91
+ return cloneElement(option.label, { onClick: newOnClick });
238
92
  };
239
- DropDown.prototype.render = function () {
240
- var _this = this;
241
- var _a = this.props, rootId = _a.rootId, rootClassName = _a.rootClassName, options = _a.options, children = _a.children;
242
- var spread = this.state.spread;
243
- var elementStyleOrClass = this.getElementStyleOrClass();
244
- var overlayRender = isValidElement(children)
245
- ? cloneElement(children, { onClick: this.handleOverlayClick })
246
- : children;
247
- return (h("div", { style: { flexDirection: 'column', flexShrink: 0 }, className: rootClassName, id: rootId, ref: this.dropdownRef },
248
- overlayRender,
249
- spread && (h("div", { ref: this.dropdownContentRef, className: typeof elementStyleOrClass.dropdownBg === 'string' ? elementStyleOrClass.dropdownBg : '', style: __assign({ flexDirection: 'column', overflow: 'scroll' }, (typeof elementStyleOrClass.dropdownBg === 'object' ? elementStyleOrClass.dropdownBg : undefined)) }, options.map(function (option, index) {
250
- return (h("div", null, _this.optionRender(option)));
251
- })))));
252
- };
253
- return DropDown;
254
- }(Component));
255
- export { DropDown };
93
+ return (h("div", { style: { flexDirection: 'column', flexShrink: 0 }, className: rootClassName, id: rootId, ref: dropdownRef },
94
+ overlayRender,
95
+ spread && (
96
+ //在下方展开
97
+ h("div", { ref: dropdownContentRef, className: typeof elementStyleOrClass.dropdownBg === 'string' ? elementStyleOrClass.dropdownBg : '', style: __assign({ flexDirection: 'column', overflow: 'scroll' }, (typeof elementStyleOrClass.dropdownBg === 'object' ? elementStyleOrClass.dropdownBg : undefined)) }, options.map(function (option, index) {
98
+ return (h("div", null, optionRender(option)));
99
+ })))));
100
+ };
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  };
12
12
  import { h } from 'preact';
13
13
  import { useEffect, useRef, useState } from 'preact/hooks';
14
- var defaulWrapperStyle = {
14
+ var defaultWrapperStyle = {
15
15
  display: 'flex',
16
16
  justifyContent: 'center',
17
17
  alignItems: 'center'
@@ -82,6 +82,14 @@ export var WheelPicker = function (props) {
82
82
  };
83
83
  var elementStyleOrClass = getElementStyleOrClass();
84
84
  var rootRef = useRef(null);
85
+ var scrollRef = useRef(null);
86
+ var scrollTimmer = useRef(null);
87
+ var isDragingRef = useRef(false);
88
+ var isInitialized = useRef(false);
89
+ var visibleItemCount = visibleAbove + visibleBelow + 1;
90
+ var _d = useState(0), itemHeight = _d[0], setItemHeight = _d[1];
91
+ var _e = useState([]), itemList = _e[0], setItemList = _e[1];
92
+ var _f = useState(visibleAbove), selectIndex = _f[0], setSelectIndex = _f[1];
85
93
  var getSelectedStyle = function (index) {
86
94
  if (elementStyleOrClass.selectedTextStyle) {
87
95
  if (index === selectIndex) {
@@ -98,41 +106,61 @@ export var WheelPicker = function (props) {
98
106
  }
99
107
  return typeof elementStyleOrClass.itemTextStyle === 'string' ? elementStyleOrClass.itemTextStyle : '';
100
108
  };
109
+ // 测量容器高度,计算 itemHeight(职责单一)
101
110
  useEffect(function () {
102
- if (rootRef.current) {
103
- var _a = rootRef.current.getBoundingClientRect(), width = _a.width, height = _a.height;
104
- var calcuItemHeight_1 = height / (visibleAbove + visibleBelow + 1);
105
- setItemHeight(calcuItemHeight_1);
106
- var defaultIndex_1 = options.indexOf(defaultOption || options[0]);
107
- setSelectIndex(defaultIndex_1 + visibleAbove);
108
- var timer_1 = setTimeout(function () {
109
- if (scrollRef.current) {
110
- scrollRef.current.scrollTop = defaultIndex_1 * calcuItemHeight_1;
111
- }
112
- }, 0);
113
- return function () { return clearTimeout(timer_1); };
114
- }
115
- }, [rootRef.current]); // 依赖 rootRef.current,当它变化时重新执行
116
- var scrollRef = useRef(null);
117
- var _d = useState(0), itemHeight = _d[0], setItemHeight = _d[1];
118
- var _e = useState([]), itemList = _e[0], setItemList = _e[1];
119
- var _f = useState(false), isDraging = _f[0], setIsDraging = _f[1];
120
- var _g = useState(0), selectIndex = _g[0], setSelectIndex = _g[1];
121
- var scrollTimmer = useRef(null);
122
- useEffect(function () {
123
- if (onChange && selectIndex - visibleAbove >= 0 && selectIndex - visibleAbove < options.length) {
124
- onChange(options[selectIndex - visibleAbove]);
111
+ var rootElement = rootRef.current;
112
+ if (!rootElement) {
113
+ return;
125
114
  }
126
- }, [selectIndex]);
115
+ var measure = function () {
116
+ var currentRoot = rootRef.current;
117
+ if (!currentRoot)
118
+ return;
119
+ var height = currentRoot.getBoundingClientRect().height;
120
+ if (height > 0) {
121
+ var calcuItemHeight = height / visibleItemCount;
122
+ setItemHeight(calcuItemHeight);
123
+ }
124
+ };
125
+ // 首次测量
126
+ measure();
127
+ // 用 requestAnimationFrame 重试,确保布局完成后能拿到正确值
128
+ var frameId = requestAnimationFrame(function () {
129
+ measure();
130
+ });
131
+ return function () { return cancelAnimationFrame(frameId); };
132
+ }, [visibleItemCount]);
133
+ // options 变化时,重建列表并重置选中索引
127
134
  useEffect(function () {
128
- setItemList(fillBlankItems());
129
- }, [props.options]);
130
- var fillBlankItems = function () {
131
135
  var startPadding = new Array(visibleAbove).fill('');
132
136
  var endPadding = new Array(visibleBelow).fill('');
133
- return startPadding.concat(options, endPadding);
134
- };
135
- // 创建一个函数来获取当前时间戳
137
+ setItemList(startPadding.concat(options, endPadding));
138
+ var defaultIndex = Math.max(0, options.indexOf(defaultOption || options[0]));
139
+ setSelectIndex(defaultIndex + visibleAbove);
140
+ isInitialized.current = false;
141
+ }, [options, visibleAbove, visibleBelow]);
142
+ // 滚动定位(与测量分离,依赖 itemHeight 和 selectIndex)
143
+ useEffect(function () {
144
+ if (itemHeight <= 0 || !scrollRef.current || isDragingRef.current || scrollTimmer.current) {
145
+ return;
146
+ }
147
+ var finalPos = (selectIndex - visibleAbove) * itemHeight;
148
+ scrollRef.current.scrollTop = finalPos;
149
+ // 标记初始化完成
150
+ if (!isInitialized.current) {
151
+ isInitialized.current = true;
152
+ }
153
+ }, [itemHeight, selectIndex, visibleAbove]);
154
+ // onChange 回调(跳过首次初始化触发)
155
+ useEffect(function () {
156
+ if (!isInitialized.current) {
157
+ return;
158
+ }
159
+ var dataIndex = selectIndex - visibleAbove;
160
+ if (onChange && dataIndex >= 0 && dataIndex < options.length) {
161
+ onChange(options[dataIndex]);
162
+ }
163
+ }, [selectIndex]);
136
164
  var getCurrentTime = function () {
137
165
  if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
138
166
  return performance.now();
@@ -142,14 +170,18 @@ export var WheelPicker = function (props) {
142
170
  }
143
171
  };
144
172
  var onScroll = function (e) {
145
- // console.log('onScroll: ', scrollRef.current.scrollTop)
173
+ if (!scrollRef.current || itemHeight <= 0)
174
+ return;
146
175
  if (scrollTimmer.current) {
147
176
  clearTimeout(scrollTimmer.current);
148
177
  scrollTimmer.current = null;
149
178
  }
150
179
  scrollTimmer.current = window.setTimeout(function () {
180
+ if (!scrollRef.current)
181
+ return;
151
182
  var finalPos = (selectIndex - visibleAbove) * itemHeight;
152
- if (!isDraging && scrollRef.current.scrollTop < finalPos - 1 || scrollRef.current.scrollTop > finalPos + 1) {
183
+ // 修复运算符优先级:整个条件都应在 !isDraging 保护下
184
+ if (!isDragingRef.current && (scrollRef.current.scrollTop < finalPos - 1 || scrollRef.current.scrollTop > finalPos + 1)) {
153
185
  animateScroll(scrollRef.current.scrollTop, finalPos, getCurrentTime(), 100);
154
186
  }
155
187
  if (scrollTimmer.current) {
@@ -164,42 +196,42 @@ export var WheelPicker = function (props) {
164
196
  };
165
197
  var animateScroll = function (currentPos, targetPos, startTime, duration) {
166
198
  var step = function () {
199
+ if (!scrollRef.current)
200
+ return;
167
201
  var currentTime = getCurrentTime();
168
202
  var time = Math.min(1, (currentTime - startTime) / duration);
169
203
  var timeFunction = time * (2 - time);
170
204
  var newPos = currentPos + (targetPos - currentPos) * timeFunction;
171
205
  scrollRef.current.scrollTop = newPos;
172
- if (time < 1 && !isDraging) {
206
+ // 使用 ref 读取最新拖拽状态,避免闭包陷阱
207
+ if (time < 1 && !isDragingRef.current) {
173
208
  requestAnimationFrame(step);
174
209
  }
175
210
  };
176
211
  requestAnimationFrame(step);
177
212
  };
178
- var onMouseEvent = function (isDraging) {
179
- if (isDraging) {
180
- setIsDraging(true);
213
+ var onMouseEvent = function (dragging) {
214
+ isDragingRef.current = dragging;
215
+ if (dragging) {
216
+ return;
181
217
  }
182
- else {
183
- setIsDraging(false);
184
- if (!scrollTimmer.current) {
185
- var finalPos = (selectIndex - visibleAbove) * itemHeight;
186
- animateScroll(scrollRef.current.scrollTop, finalPos, getCurrentTime(), 100);
187
- var nowSelectIndex = Math.round((scrollRef.current.scrollTop + visibleAbove * itemHeight) / itemHeight);
188
- if (selectIndex !== nowSelectIndex) {
189
- setSelectIndex(nowSelectIndex);
190
- }
218
+ // 松手后对齐
219
+ if (!scrollTimmer.current && scrollRef.current && itemHeight > 0) {
220
+ var finalPos = (selectIndex - visibleAbove) * itemHeight;
221
+ animateScroll(scrollRef.current.scrollTop, finalPos, getCurrentTime(), 100);
222
+ var nowSelectIndex = Math.round((scrollRef.current.scrollTop + visibleAbove * itemHeight) / itemHeight);
223
+ if (selectIndex !== nowSelectIndex) {
224
+ setSelectIndex(nowSelectIndex);
191
225
  }
192
226
  }
193
227
  };
194
- return (h("div", { id: rootId, className: rootClassName, style: __assign({}, defaulWrapperStyle), ref: rootRef },
228
+ return (h("div", { id: rootId, className: rootClassName, style: __assign({}, defaultWrapperStyle), ref: rootRef },
195
229
  elementStyleOrClass.selectedAreaStyle &&
196
230
  h("div", { className: typeof elementStyleOrClass.selectedAreaStyle === 'string' ? elementStyleOrClass.selectedAreaStyle : '', style: __assign(__assign(__assign({}, (typeof elementStyleOrClass.selectedAreaStyle === 'object' ? elementStyleOrClass.selectedAreaStyle : undefined)), maskAreaStyle), { height: "".concat(itemHeight, "px"), top: "".concat(itemHeight * visibleAbove, "px") }) }),
197
231
  elementStyleOrClass.AboveMaskAreaStyle &&
198
232
  h("div", { className: typeof elementStyleOrClass.AboveMaskAreaStyle === 'string' ? elementStyleOrClass.AboveMaskAreaStyle : '', style: __assign(__assign(__assign({}, (typeof elementStyleOrClass.AboveMaskAreaStyle === 'object' ? elementStyleOrClass.AboveMaskAreaStyle : undefined)), maskAreaStyle), { height: "".concat(itemHeight * visibleAbove, "px"), top: '0px' }) }),
199
233
  elementStyleOrClass.BelowMaskAreaStyle &&
200
234
  h("div", { className: typeof elementStyleOrClass.BelowMaskAreaStyle === 'string' ? elementStyleOrClass.BelowMaskAreaStyle : '', style: __assign(__assign(__assign({}, (typeof elementStyleOrClass.BelowMaskAreaStyle === 'object' ? elementStyleOrClass.BelowMaskAreaStyle : undefined)), maskAreaStyle), { height: "".concat(itemHeight * visibleBelow, "px"), top: "".concat(itemHeight * (visibleAbove + 1), "px") }) }),
201
- h("div", { style: __assign({}, defaultScrollStyle),
202
- // movement-type={'clamped'}
203
- ref: scrollRef, onScroll: function (e) { onScroll(e); }, onMouseDown: function () { onMouseEvent(true); }, onMouseUp: function () { onMouseEvent(false); } }, itemList.map(function (item, index) { return (h("div", { style: __assign(__assign({}, defaultItemStyle), { minHeight: "".concat(itemHeight, "px"), maxHeight: "".concat(itemHeight, "px") }) },
235
+ h("div", { style: __assign({}, defaultScrollStyle), ref: scrollRef, onScroll: function (e) { onScroll(e); }, onMouseDown: function () { onMouseEvent(true); }, onMouseUp: function () { onMouseEvent(false); } }, itemList.map(function (item, index) { return (h("div", { key: index, style: __assign(__assign({}, defaultItemStyle), { minHeight: "".concat(itemHeight, "px"), maxHeight: "".concat(itemHeight, "px") }) },
204
236
  h("div", { className: getSelectedClass(index), style: getSelectedStyle(index) }, item))); }))));
205
237
  };