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,4 +1,4 @@
|
|
|
1
|
-
import preact, { CSSProperties, h
|
|
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
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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 =
|
|
162
|
-
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
231
|
-
|
|
232
|
-
if (
|
|
233
|
-
return
|
|
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
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
179
|
-
|
|
180
|
-
|
|
213
|
+
var onMouseEvent = function (dragging) {
|
|
214
|
+
isDragingRef.current = dragging;
|
|
215
|
+
if (dragging) {
|
|
216
|
+
return;
|
|
181
217
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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({},
|
|
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
|
};
|