@ncdai/react-wheel-picker 1.0.16 → 1.0.18

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/README.md CHANGED
@@ -17,3 +17,11 @@ Please read the [documentation](https://react-wheel-picker.chanhdai.com/docs/get
17
17
  ## License
18
18
 
19
19
  Licensed under the [MIT license](./LICENSE).
20
+
21
+ ## Sponsors
22
+
23
+ This project is proudly supported by:
24
+
25
+ [![Vercel OSS Program](https://vercel.com/oss/program-badge.svg)](https://vercel.com/blog/summer-2025-oss-program#react-wheel-picker)
26
+
27
+ > Using this package at work? [Sponsor me](https://github.com/sponsors/ncdai) to help with support and maintenance.
package/dist/index.d.mts CHANGED
@@ -1,11 +1,15 @@
1
1
  import React, { ReactNode } from 'react';
2
2
 
3
+ /**
4
+ * Represents the value of a single option in the wheel picker
5
+ */
6
+ type WheelPickerValue = string | number;
3
7
  /**
4
8
  * Represents a single option in the wheel picker
5
9
  */
6
- type WheelPickerOption = {
10
+ type WheelPickerOption<T extends WheelPickerValue = string> = {
7
11
  /** The value that will be returned when this option is selected */
8
- value: string;
12
+ value: T;
9
13
  /** The content displayed for this option */
10
14
  label: ReactNode;
11
15
  };
@@ -23,15 +27,15 @@ type WheelPickerClassNames = {
23
27
  /**
24
28
  * Props for the WheelPicker component
25
29
  */
26
- type WheelPickerProps = {
30
+ type WheelPickerProps<T extends WheelPickerValue = string> = {
27
31
  /** Initial value of the picker when uncontrolled */
28
- defaultValue?: string;
32
+ defaultValue?: T;
29
33
  /** Current value of the picker when controlled */
30
- value?: string;
34
+ value?: T;
31
35
  /** Callback fired when the selected value changes */
32
- onValueChange?: (value: string) => void;
36
+ onValueChange?: (value: T) => void;
33
37
  /** Array of options to display in the wheel */
34
- options: WheelPickerOption[];
38
+ options: WheelPickerOption<T>[];
35
39
  /** Whether the wheel should loop infinitely */
36
40
  infinite?: boolean;
37
41
  /** The number of options visible on the circular ring, must be a multiple of 4 */
@@ -56,6 +60,6 @@ type WheelPickerWrapperProps = {
56
60
  };
57
61
 
58
62
  declare const WheelPickerWrapper: React.FC<WheelPickerWrapperProps>;
59
- declare const WheelPicker: React.FC<WheelPickerProps>;
63
+ declare function WheelPicker<T extends WheelPickerValue>({ defaultValue, value: valueProp, onValueChange, options: optionsProp, infinite: infiniteProp, visibleCount: countProp, dragSensitivity: dragSensitivityProp, scrollSensitivity: scrollSensitivityProp, optionItemHeight: optionHeightProp, classNames, }: WheelPickerProps<T>): React.JSX.Element;
60
64
 
61
- export { WheelPicker, type WheelPickerClassNames, type WheelPickerOption, WheelPickerWrapper };
65
+ export { WheelPicker, type WheelPickerClassNames, type WheelPickerOption, type WheelPickerProps, type WheelPickerValue, WheelPickerWrapper };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import React, { ReactNode } from 'react';
2
2
 
3
+ /**
4
+ * Represents the value of a single option in the wheel picker
5
+ */
6
+ type WheelPickerValue = string | number;
3
7
  /**
4
8
  * Represents a single option in the wheel picker
5
9
  */
6
- type WheelPickerOption = {
10
+ type WheelPickerOption<T extends WheelPickerValue = string> = {
7
11
  /** The value that will be returned when this option is selected */
8
- value: string;
12
+ value: T;
9
13
  /** The content displayed for this option */
10
14
  label: ReactNode;
11
15
  };
@@ -23,15 +27,15 @@ type WheelPickerClassNames = {
23
27
  /**
24
28
  * Props for the WheelPicker component
25
29
  */
26
- type WheelPickerProps = {
30
+ type WheelPickerProps<T extends WheelPickerValue = string> = {
27
31
  /** Initial value of the picker when uncontrolled */
28
- defaultValue?: string;
32
+ defaultValue?: T;
29
33
  /** Current value of the picker when controlled */
30
- value?: string;
34
+ value?: T;
31
35
  /** Callback fired when the selected value changes */
32
- onValueChange?: (value: string) => void;
36
+ onValueChange?: (value: T) => void;
33
37
  /** Array of options to display in the wheel */
34
- options: WheelPickerOption[];
38
+ options: WheelPickerOption<T>[];
35
39
  /** Whether the wheel should loop infinitely */
36
40
  infinite?: boolean;
37
41
  /** The number of options visible on the circular ring, must be a multiple of 4 */
@@ -56,6 +60,6 @@ type WheelPickerWrapperProps = {
56
60
  };
57
61
 
58
62
  declare const WheelPickerWrapper: React.FC<WheelPickerWrapperProps>;
59
- declare const WheelPicker: React.FC<WheelPickerProps>;
63
+ declare function WheelPicker<T extends WheelPickerValue>({ defaultValue, value: valueProp, onValueChange, options: optionsProp, infinite: infiniteProp, visibleCount: countProp, dragSensitivity: dragSensitivityProp, scrollSensitivity: scrollSensitivityProp, optionItemHeight: optionHeightProp, classNames, }: WheelPickerProps<T>): React.JSX.Element;
60
64
 
61
- export { WheelPicker, type WheelPickerClassNames, type WheelPickerOption, WheelPickerWrapper };
65
+ export { WheelPicker, type WheelPickerClassNames, type WheelPickerOption, type WheelPickerProps, type WheelPickerValue, WheelPickerWrapper };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";"use client";var kt=Object.create;var A=Object.defineProperty;var Et=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Ct=Object.getPrototypeOf,It=Object.prototype.hasOwnProperty;var Lt=(s,a)=>{for(var d in a)A(s,d,{get:a[d],enumerable:!0})},at=(s,a,d,f)=>{if(a&&typeof a=="object"||typeof a=="function")for(let c of Dt(a))!It.call(s,c)&&c!==d&&A(s,c,{get:()=>a[c],enumerable:!(f=Et(a,c))||f.enumerable});return s};var it=(s,a,d)=>(d=s!=null?kt(Ct(s)):{},at(a||!s||!s.__esModule?A(d,"default",{value:s,enumerable:!0}):d,s)),Wt=s=>at(A({},"__esModule",{value:!0}),s);var Ot={};Lt(Ot,{WheelPicker:()=>Ht,WheelPickerWrapper:()=>Rt});module.exports=Wt(Ot);var S=it(require("react")),h=require("react");var T=it(require("react"));function ct(s){let a=T.default.useRef(s);return T.default.useEffect(()=>{a.current=s}),T.default.useMemo(()=>(...d)=>{var f;return(f=a.current)==null?void 0:f.call(a,...d)},[])}function xt({defaultProp:s,onChange:a}){let d=T.default.useState(s),[f]=d,c=T.default.useRef(f),w=ct(a);return T.default.useEffect(()=>{c.current!==f&&(w(f),c.current=f)},[f,c,w]),d}function lt({prop:s,defaultProp:a,onChange:d=()=>{}}){let[f,c]=xt({defaultProp:a,onChange:d}),w=s!==void 0,R=w?s:f,C=ct(d),H=T.default.useCallback(g=>{if(w){let I=typeof g=="function"?g(s):g;I!==s&&C(I)}else c(g)},[w,s,c,C]);return[R,H]}var ut=.3,Yt=30,At=s=>Math.pow(s-1,3)+1,j=(s,a,d)=>Math.max(a,Math.min(s,d)),Rt=({className:s,children:a})=>S.default.createElement("div",{className:s,"data-rwp-wrapper":!0},a),Ht=({defaultValue:s,value:a,onValueChange:d,options:f,infinite:c=!1,visibleCount:w=20,dragSensitivity:R=3,scrollSensitivity:C=5,optionItemHeight:H=30,classNames:g})=>{var nt,rt;let[O=(rt=(nt=f[0])==null?void 0:nt.value)!=null?rt:"",I]=lt({defaultProp:s,prop:a,onChange:d}),i=(0,h.useMemo)(()=>{if(!c)return f;let t=[],n=Math.ceil(w/2);if(f.length===0)return t;for(;t.length<n;)t.push(...f);return t},[w,f,c]),p=H,X=p*.5,M=360/w,L=p/Math.tan(M*Math.PI/180),ht=Math.round(L*2+p*.25),k=w>>2,G=R*10,dt=10,b=(0,h.useRef)(null),W=(0,h.useRef)(null),z=(0,h.useRef)(null),v=(0,h.useRef)(0),Z=(0,h.useRef)(0),E=(0,h.useRef)(!1),K=(0,h.useRef)(0),P=(0,h.useRef)({startY:0,yList:[],touchScroll:0,isClick:!0}),F=(0,h.useRef)(null),gt=(0,h.useMemo)(()=>{let t=(e,r,o)=>S.default.createElement("li",{key:r,className:g==null?void 0:g.optionItem,"data-slot":"option-item","data-rwp-option":!0,"data-index":r,style:{top:-X,height:p,lineHeight:`${p}px`,transform:`rotateX(${o}deg) translateZ(${L}px)`,visibility:"hidden"}},e.label),n=i.map((e,r)=>t(e,r,-M*r));if(c)for(let e=0;e<k;++e){let r=-e-1,o=e+i.length;n.unshift(t(i[i.length-e-1],r,M*(e+1))),n.push(t(i[e],o,-M*o))}return n},[p,X,c,M,i,k,L,g==null?void 0:g.optionItem]),ft=(0,h.useMemo)(()=>{let t=(e,r)=>S.default.createElement("li",{key:r,className:g==null?void 0:g.highlightItem,"data-slot":"highlight-item","data-rwp-highlight-item":!0,style:{height:p}},e.label),n=i.map((e,r)=>t(e,r));if(c){let e=i[0],r=i[i.length-1];n.unshift(t(r,"infinite-start")),n.push(t(e,"infinite-end"))}return n},[g==null?void 0:g.highlightItem,p,c,i]),pt=(0,h.useMemo)(()=>{let t=0,n=Math.PI/180,e=[];for(let r=k-1;r>=-k+1;--r){let o=r*M,u=p*Math.cos(o*n),l=t;t+=u,e.push([l,t])}return e},[M,p,k]),U=t=>(t%i.length+i.length)%i.length,D=t=>{let n=c?U(t):t;if(W.current){let e=`translateZ(${-L}px) rotateX(${M*n}deg)`;W.current.style.transform=e,W.current.childNodes.forEach(r=>{let o=r,u=Math.abs(Number(o.dataset.index)-n);o.style.visibility=u>k?"hidden":"visible"})}return z.current&&(z.current.style.transform=`translateY(${-n*p}px)`),n},x=()=>{cancelAnimationFrame(Z.current)},_=(t,n,e,r)=>{if(t===n||e===0){D(t);return}let o=performance.now(),u=n-t,l=m=>{let y=(m-o)/1e3;if(y<e){let B=At(y/e);v.current=D(t+B*u),Z.current=requestAnimationFrame(l)}else x(),v.current=D(n),r==null||r()};requestAnimationFrame(l)},Y=t=>{let n=U(t)|0,e=c?n:Math.min(Math.max(n,0),i.length-1);if(!c&&e!==t)return;v.current=D(e);let r=i[v.current];I(r.value)},mt=t=>{let n=i.findIndex(e=>e.value===t);if(n===-1){console.error("Invalid value selected:",t);return}x(),Y(n)},J=t=>{let n=v.current,e=n+t;c?e=Math.round(e):e=j(Math.round(e),0,i.length-1);let r=Math.abs(e-n);if(r===0)return;let o=Math.sqrt(r/C);x(),_(n,e,o,()=>{Y(v.current)})},bt=t=>{let n=b.current;if(!n){console.error("Container reference is not set.");return}let{top:e}=n.getBoundingClientRect(),r=t-e,o=pt.findIndex(([l,m])=>r>=l&&r<=m);if(o===-1){console.error("No item found for click position:",r);return}let u=(k-o-1)*-1;J(u)},vt=t=>{var n,e;try{let r=(t instanceof MouseEvent?t.clientY:(e=(n=t.touches)==null?void 0:n[0])==null?void 0:e.clientY)||0,o=P.current;o.isClick&&Math.abs(r-o.startY)>5&&(o.isClick=!1),o.yList.push([r,Date.now()]),o.yList.length>5&&o.yList.shift();let u=(o.startY-r)/p,l=v.current+u;if(c)l=U(l);else{let m=i.length;l<0?l*=ut:l>m&&(l=m+(l-m)*ut)}o.touchScroll=D(l)}catch(r){console.error("Error in updateScrollDuringDrag:",r)}},Q=t=>{!E.current&&!b.current.contains(t.target)&&t.target!==b.current||(t.cancelable&&t.preventDefault(),i.length&&vt(t))},V=t=>{var n,e,r;try{E.current=!0;let o=new AbortController,{signal:u}=o;F.current=o;let l={signal:u,passive:!1};(n=b.current)==null||n.addEventListener("touchmove",Q,l),document.addEventListener("mousemove",Q,l);let m=(t instanceof MouseEvent?t.clientY:(r=(e=t.touches)==null?void 0:e[0])==null?void 0:r.clientY)||0,y=P.current;y.startY=m,y.yList=[[m,Date.now()]],y.touchScroll=v.current,y.isClick=!0,x()}catch(o){console.error("Error in initiateDragGesture:",o)}},$=(0,h.useCallback)(t=>{let n=E.current,e=b.current.contains(t.target)||t.target===b.current;(n||e)&&t.cancelable&&(t.preventDefault(),i.length&&V(t))},[V]),wt=t=>{let n=v.current,e=n,r=t>0?-G:G,o=0;if(c){o=Math.abs(t/r);let u=t*o+.5*r*o*o;e=Math.round(n+u)}else if(n<0||n>i.length-1){let u=j(n,0,i.length-1),l=n-u;r=dt,o=Math.sqrt(Math.abs(l/r)),t=r*o,t=n>0?-t:t,e=u}else{o=Math.abs(t/r);let u=t*o+.5*r*o*o;e=Math.round(n+u),e=j(e,0,i.length-1);let l=e-n;o=Math.sqrt(Math.abs(l/r))}_(n,e,o,()=>{Y(v.current)}),Y(v.current)},N=()=>{var t,n,e,r;try{(t=F.current)==null||t.abort(),F.current=null;let o=P.current;if(o.isClick){bt(o.startY);return}let u=o.yList,l=0;if(u.length>1){let m=u.length,[y,B]=(n=u[m-2])!=null?n:[0,0],[yt,Mt]=(e=u[m-1])!=null?e:[0,0],ot=Mt-B;if(ot>0){let st=(y-yt)/p*1e3/ot,Tt=Yt,St=st>0?1:-1;l=Math.min(Math.abs(st),Tt)*St}}v.current=(r=o.touchScroll)!=null?r:v.current,wt(l)}catch(o){console.error("Error in finalizeDragAndStartInertiaScroll:",o)}finally{E.current=!1}},q=(0,h.useCallback)(t=>{if(!i.length)return;let n=E.current,e=b.current.contains(t.target)||t.target===b.current;(n||e)&&t.cancelable&&(t.preventDefault(),N())},[N]),tt=t=>{t.preventDefault();let n=Date.now();if(n-K.current<100)return;let e=Math.sign(t.deltaY);e&&(K.current=n,J(e))},et=(0,h.useCallback)(t=>{if(!i.length||!b.current)return;let n=E.current,e=b.current.contains(t.target)||t.target===b.current;(n||e)&&t.cancelable&&(t.preventDefault(),tt(t))},[tt]);return(0,h.useEffect)(()=>{let t=b.current;if(!t)return;let n=new AbortController,{signal:e}=n,r={signal:e,passive:!1};return t.addEventListener("touchstart",$,r),t.addEventListener("touchend",q,r),t.addEventListener("wheel",et,r),document.addEventListener("mousedown",$,r),document.addEventListener("mouseup",q,r),()=>n.abort()},[q,$,et]),(0,h.useEffect)(()=>{mt(O)},[O,a,i]),S.default.createElement("div",{ref:b,"data-rwp":!0,style:{height:ht}},S.default.createElement("ul",{ref:W,"data-rwp-options":!0},gt),S.default.createElement("div",{className:g==null?void 0:g.highlightWrapper,"data-rwp-highlight-wrapper":!0,"data-slot":"highlight-wrapper",style:{height:p,lineHeight:`${p}px`}},S.default.createElement("ul",{ref:z,"data-rwp-highlight-list":!0,style:{top:c?-p:void 0}},ft)))};0&&(module.exports={WheelPicker,WheelPickerWrapper});
1
+ "use strict";"use client";var kt=Object.create;var P=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var St=Object.getOwnPropertyNames;var Dt=Object.getPrototypeOf,Lt=Object.prototype.hasOwnProperty;var It=(s,a)=>{for(var d in a)P(s,d,{get:a[d],enumerable:!0})},st=(s,a,d,f)=>{if(a&&typeof a=="object"||typeof a=="function")for(let c of St(a))!Lt.call(s,c)&&c!==d&&P(s,c,{get:()=>a[c],enumerable:!(f=Mt(a,c))||f.enumerable});return s};var at=(s,a,d)=>(d=s!=null?kt(Dt(s)):{},st(a||!s||!s.__esModule?P(d,"default",{value:s,enumerable:!0}):d,s)),Wt=s=>st(P({},"__esModule",{value:!0}),s);var Pt={};It(Pt,{WheelPicker:()=>Rt,WheelPickerWrapper:()=>At});module.exports=Wt(Pt);var k=at(require("react")),h=require("react");var E=at(require("react"));function it(s){let a=E.default.useRef(s);return E.default.useEffect(()=>{a.current=s}),E.default.useMemo(()=>(...d)=>{var f;return(f=a.current)==null?void 0:f.call(a,...d)},[])}function Ct({defaultProp:s,onChange:a}){let d=E.default.useState(s),[f]=d,c=E.default.useRef(f),w=it(a);return E.default.useEffect(()=>{c.current!==f&&(w(f),c.current=f)},[f,c,w]),d}function ct({prop:s,defaultProp:a,onChange:d=()=>{}}){let[f,c]=Ct({defaultProp:a,onChange:d}),w=s!==void 0,H=w?s:f,W=it(d),O=E.default.useCallback(g=>{if(w){let C=typeof g=="function"?g(s):g;C!==s&&W(C)}else c(g)},[w,s,c,W]);return[H,O]}var lt=.3,xt=30,Yt=s=>Math.pow(s-1,3)+1,V=(s,a,d)=>Math.max(a,Math.min(s,d)),At=({className:s,children:a})=>k.default.createElement("div",{className:s,"data-rwp-wrapper":!0},a);function Rt({defaultValue:s,value:a,onValueChange:d,options:f,infinite:c=!1,visibleCount:w=20,dragSensitivity:H=3,scrollSensitivity:W=5,optionItemHeight:O=30,classNames:g}){var nt;let[z=(nt=f[0])==null?void 0:nt.value,C]=ct({defaultProp:s,prop:a,onChange:d}),i=(0,h.useMemo)(()=>{if(!c)return f;let t=[],e=Math.ceil(w/2);if(f.length===0)return t;for(;t.length<e;)t.push(...f);return t},[w,f,c]),p=O,X=p*.5,y=360/w,x=p/Math.tan(y*Math.PI/180),ut=Math.round(x*2+p*.25),M=w>>2,G=H*10,ht=10,b=(0,h.useRef)(null),Y=(0,h.useRef)(null),U=(0,h.useRef)(null),v=(0,h.useRef)(0),Z=(0,h.useRef)(0),S=(0,h.useRef)(!1),K=(0,h.useRef)(0),$=(0,h.useRef)({startY:0,yList:[],touchScroll:0,isClick:!0}),q=(0,h.useRef)(null),dt=(0,h.useMemo)(()=>{let t=(n,r,o)=>k.default.createElement("li",{key:r,className:g==null?void 0:g.optionItem,"data-slot":"option-item","data-rwp-option":!0,"data-index":r,style:{top:-X,height:p,lineHeight:`${p}px`,transform:`rotateX(${o}deg) translateZ(${x}px)`,visibility:"hidden"}},n.label),e=i.map((n,r)=>t(n,r,-y*r));if(c)for(let n=0;n<M;++n){let r=-n-1,o=n+i.length;e.unshift(t(i[i.length-n-1],r,y*(n+1))),e.push(t(i[n],o,-y*o))}return e},[p,X,c,y,i,M,x,g==null?void 0:g.optionItem]),gt=(0,h.useMemo)(()=>{let t=(n,r)=>k.default.createElement("li",{key:r,className:g==null?void 0:g.highlightItem,"data-slot":"highlight-item","data-rwp-highlight-item":!0,style:{height:p}},n.label),e=i.map((n,r)=>t(n,r));if(c){let n=i[0],r=i[i.length-1];e.unshift(t(r,"infinite-start")),e.push(t(n,"infinite-end"))}return e},[g==null?void 0:g.highlightItem,p,c,i]),ft=(0,h.useMemo)(()=>{let t=0,e=Math.PI/180,n=[];for(let r=M-1;r>=-M+1;--r){let o=r*y,u=p*Math.cos(o*e),l=t;t+=u,n.push([l,t])}return n},[y,p,M]),B=t=>(t%i.length+i.length)%i.length,D=t=>{let e=c?B(t):t;if(Y.current){let n=`translateZ(${-x}px) rotateX(${y*e}deg)`;Y.current.style.transform=n,Y.current.childNodes.forEach(r=>{let o=r,u=Math.abs(Number(o.dataset.index)-e);o.style.visibility=u>M?"hidden":"visible"})}return U.current&&(U.current.style.transform=`translateY(${-e*p}px)`),e},A=()=>{cancelAnimationFrame(Z.current)},_=(t,e,n,r)=>{if(t===e||n===0){D(t);return}let o=performance.now(),u=e-t,l=m=>{let T=(m-o)/1e3;if(T<n){let j=Yt(T/n);v.current=D(t+j*u),Z.current=requestAnimationFrame(l)}else A(),v.current=D(e),r==null||r()};requestAnimationFrame(l)},R=t=>{let e=B(t)|0,n=c?e:Math.min(Math.max(e,0),i.length-1);if(!c&&n!==t)return;v.current=D(n);let r=i[v.current];C(r.value)},pt=t=>{let e=i.findIndex(n=>n.value===t);if(e===-1){console.error("Invalid value selected:",t);return}A(),R(e)},J=t=>{let e=v.current,n=e+t;c?n=Math.round(n):n=V(Math.round(n),0,i.length-1);let r=Math.abs(n-e);if(r===0)return;let o=Math.sqrt(r/W);A(),_(e,n,o,()=>{R(v.current)})},mt=t=>{let e=b.current;if(!e){console.error("Container reference is not set.");return}let{top:n}=e.getBoundingClientRect(),r=t-n,o=ft.findIndex(([l,m])=>r>=l&&r<=m);if(o===-1){console.error("No item found for click position:",r);return}let u=(M-o-1)*-1;J(u)},bt=t=>{var e,n;try{let r=(t instanceof MouseEvent?t.clientY:(n=(e=t.touches)==null?void 0:e[0])==null?void 0:n.clientY)||0,o=$.current;o.isClick&&Math.abs(r-o.startY)>5&&(o.isClick=!1),o.yList.push([r,Date.now()]),o.yList.length>5&&o.yList.shift();let u=(o.startY-r)/p,l=v.current+u;if(c)l=B(l);else{let m=i.length;l<0?l*=lt:l>m&&(l=m+(l-m)*lt)}o.touchScroll=D(l)}catch(r){console.error("Error in updateScrollDuringDrag:",r)}},Q=t=>{var e;!S.current&&!((e=b.current)!=null&&e.contains(t.target))&&t.target!==b.current||(t.cancelable&&t.preventDefault(),i.length&&bt(t))},N=t=>{var e,n,r;try{S.current=!0;let o=new AbortController,{signal:u}=o;q.current=o;let l={signal:u,passive:!1};(e=b.current)==null||e.addEventListener("touchmove",Q,l),document.addEventListener("mousemove",Q,l);let m=(t instanceof MouseEvent?t.clientY:(r=(n=t.touches)==null?void 0:n[0])==null?void 0:r.clientY)||0,T=$.current;T.startY=m,T.yList=[[m,Date.now()]],T.touchScroll=v.current,T.isClick=!0,A()}catch(o){console.error("Error in initiateDragGesture:",o)}},L=(0,h.useCallback)(t=>{var r;let e=S.current,n=!!((r=b.current)!=null&&r.contains(t.target))||t.target===b.current;(e||n)&&t.cancelable&&(t.preventDefault(),i.length&&N(t))},[N]),vt=t=>{let e=v.current,n=e,r=t>0?-G:G,o=0;if(c){o=Math.abs(t/r);let u=t*o+.5*r*o*o;n=Math.round(e+u)}else if(e<0||e>i.length-1){let u=V(e,0,i.length-1),l=e-u;r=ht,o=Math.sqrt(Math.abs(l/r)),t=r*o,t=e>0?-t:t,n=u}else{o=Math.abs(t/r);let u=t*o+.5*r*o*o;n=Math.round(e+u),n=V(n,0,i.length-1);let l=n-e;o=Math.sqrt(Math.abs(l/r))}_(e,n,o,()=>{R(v.current)}),R(v.current)},tt=()=>{var t,e,n,r;try{(t=q.current)==null||t.abort(),q.current=null;let o=$.current;if(o.isClick){mt(o.startY);return}let u=o.yList,l=0;if(u.length>1){let m=u.length,[T,j]=(e=u[m-2])!=null?e:[0,0],[wt,Tt]=(n=u[m-1])!=null?n:[0,0],rt=Tt-j;if(rt>0){let ot=(T-wt)/p*1e3/rt,yt=xt,Et=ot>0?1:-1;l=Math.min(Math.abs(ot),yt)*Et}}v.current=(r=o.touchScroll)!=null?r:v.current,vt(l)}catch(o){console.error("Error in finalizeDragAndStartInertiaScroll:",o)}finally{S.current=!1}},I=(0,h.useCallback)(t=>{var r;if(!i.length)return;let e=S.current,n=!!((r=b.current)!=null&&r.contains(t.target))||t.target===b.current;(e||n)&&t.cancelable&&(t.preventDefault(),tt())},[tt]),et=t=>{t.preventDefault();let e=Date.now();if(e-K.current<100)return;let n=Math.sign(t.deltaY);n&&(K.current=e,J(n))},F=(0,h.useCallback)(t=>{if(!i.length||!b.current)return;let e=S.current,n=b.current.contains(t.target)||t.target===b.current;(e||n)&&t.cancelable&&(t.preventDefault(),et(t))},[et]);return(0,h.useEffect)(()=>{let t=b.current;if(!t)return;let e={passive:!1};return t.addEventListener("touchstart",L,e),t.addEventListener("touchend",I,e),t.addEventListener("wheel",F,e),document.addEventListener("mousedown",L,e),document.addEventListener("mouseup",I,e),()=>{t.removeEventListener("touchstart",L),t.removeEventListener("touchend",I),t.removeEventListener("wheel",F),document.removeEventListener("mousedown",L),document.removeEventListener("mouseup",I)}},[I,L,F]),(0,h.useEffect)(()=>{pt(z)},[z,a,i]),k.default.createElement("div",{ref:b,"data-rwp":!0,style:{height:ut}},k.default.createElement("ul",{ref:Y,"data-rwp-options":!0},dt),k.default.createElement("div",{className:g==null?void 0:g.highlightWrapper,"data-rwp-highlight-wrapper":!0,"data-slot":"highlight-wrapper",style:{height:p,lineHeight:`${p}px`}},k.default.createElement("ul",{ref:U,"data-rwp-highlight-list":!0,style:{top:c?-p:void 0}},gt)))}0&&(module.exports={WheelPicker,WheelPickerWrapper});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- "use client";import k from"react";import{useCallback as j,useEffect as lt,useMemo as A,useRef as y}from"react";import S from"react";function it(u){let g=S.useRef(u);return S.useEffect(()=>{g.current=u}),S.useMemo(()=>(...b)=>{var h;return(h=g.current)==null?void 0:h.call(g,...b)},[])}function kt({defaultProp:u,onChange:g}){let b=S.useState(u),[h]=b,c=S.useRef(h),v=it(g);return S.useEffect(()=>{c.current!==h&&(v(h),c.current=h)},[h,c,v]),b}function ct({prop:u,defaultProp:g,onChange:b=()=>{}}){let[h,c]=kt({defaultProp:g,onChange:b}),v=u!==void 0,R=v?u:h,C=it(b),H=S.useCallback(l=>{if(v){let I=typeof l=="function"?l(u):l;I!==u&&C(I)}else c(l)},[v,u,c,C]);return[R,H]}var ut=.3,Et=30,Dt=u=>Math.pow(u-1,3)+1,X=(u,g,b)=>Math.max(g,Math.min(u,b)),zt=({className:u,children:g})=>k.createElement("div",{className:u,"data-rwp-wrapper":!0},g),Pt=({defaultValue:u,value:g,onValueChange:b,options:h,infinite:c=!1,visibleCount:v=20,dragSensitivity:R=3,scrollSensitivity:C=5,optionItemHeight:H=30,classNames:l})=>{var rt,ot;let[O=(ot=(rt=h[0])==null?void 0:rt.value)!=null?ot:"",I]=ct({defaultProp:u,prop:g,onChange:b}),s=A(()=>{if(!c)return h;let t=[],n=Math.ceil(v/2);if(h.length===0)return t;for(;t.length<n;)t.push(...h);return t},[v,h,c]),d=H,G=d*.5,M=360/v,L=d/Math.tan(M*Math.PI/180),ht=Math.round(L*2+d*.25),T=v>>2,Z=R*10,dt=10,p=y(null),W=y(null),z=y(null),m=y(0),K=y(0),E=y(!1),_=y(0),P=y({startY:0,yList:[],touchScroll:0,isClick:!0}),F=y(null),gt=A(()=>{let t=(e,r,o)=>k.createElement("li",{key:r,className:l==null?void 0:l.optionItem,"data-slot":"option-item","data-rwp-option":!0,"data-index":r,style:{top:-G,height:d,lineHeight:`${d}px`,transform:`rotateX(${o}deg) translateZ(${L}px)`,visibility:"hidden"}},e.label),n=s.map((e,r)=>t(e,r,-M*r));if(c)for(let e=0;e<T;++e){let r=-e-1,o=e+s.length;n.unshift(t(s[s.length-e-1],r,M*(e+1))),n.push(t(s[e],o,-M*o))}return n},[d,G,c,M,s,T,L,l==null?void 0:l.optionItem]),ft=A(()=>{let t=(e,r)=>k.createElement("li",{key:r,className:l==null?void 0:l.highlightItem,"data-slot":"highlight-item","data-rwp-highlight-item":!0,style:{height:d}},e.label),n=s.map((e,r)=>t(e,r));if(c){let e=s[0],r=s[s.length-1];n.unshift(t(r,"infinite-start")),n.push(t(e,"infinite-end"))}return n},[l==null?void 0:l.highlightItem,d,c,s]),pt=A(()=>{let t=0,n=Math.PI/180,e=[];for(let r=T-1;r>=-T+1;--r){let o=r*M,i=d*Math.cos(o*n),a=t;t+=i,e.push([a,t])}return e},[M,d,T]),U=t=>(t%s.length+s.length)%s.length,D=t=>{let n=c?U(t):t;if(W.current){let e=`translateZ(${-L}px) rotateX(${M*n}deg)`;W.current.style.transform=e,W.current.childNodes.forEach(r=>{let o=r,i=Math.abs(Number(o.dataset.index)-n);o.style.visibility=i>T?"hidden":"visible"})}return z.current&&(z.current.style.transform=`translateY(${-n*d}px)`),n},x=()=>{cancelAnimationFrame(K.current)},J=(t,n,e,r)=>{if(t===n||e===0){D(t);return}let o=performance.now(),i=n-t,a=f=>{let w=(f-o)/1e3;if(w<e){let B=Dt(w/e);m.current=D(t+B*i),K.current=requestAnimationFrame(a)}else x(),m.current=D(n),r==null||r()};requestAnimationFrame(a)},Y=t=>{let n=U(t)|0,e=c?n:Math.min(Math.max(n,0),s.length-1);if(!c&&e!==t)return;m.current=D(e);let r=s[m.current];I(r.value)},mt=t=>{let n=s.findIndex(e=>e.value===t);if(n===-1){console.error("Invalid value selected:",t);return}x(),Y(n)},Q=t=>{let n=m.current,e=n+t;c?e=Math.round(e):e=X(Math.round(e),0,s.length-1);let r=Math.abs(e-n);if(r===0)return;let o=Math.sqrt(r/C);x(),J(n,e,o,()=>{Y(m.current)})},bt=t=>{let n=p.current;if(!n){console.error("Container reference is not set.");return}let{top:e}=n.getBoundingClientRect(),r=t-e,o=pt.findIndex(([a,f])=>r>=a&&r<=f);if(o===-1){console.error("No item found for click position:",r);return}let i=(T-o-1)*-1;Q(i)},vt=t=>{var n,e;try{let r=(t instanceof MouseEvent?t.clientY:(e=(n=t.touches)==null?void 0:n[0])==null?void 0:e.clientY)||0,o=P.current;o.isClick&&Math.abs(r-o.startY)>5&&(o.isClick=!1),o.yList.push([r,Date.now()]),o.yList.length>5&&o.yList.shift();let i=(o.startY-r)/d,a=m.current+i;if(c)a=U(a);else{let f=s.length;a<0?a*=ut:a>f&&(a=f+(a-f)*ut)}o.touchScroll=D(a)}catch(r){console.error("Error in updateScrollDuringDrag:",r)}},V=t=>{!E.current&&!p.current.contains(t.target)&&t.target!==p.current||(t.cancelable&&t.preventDefault(),s.length&&vt(t))},N=t=>{var n,e,r;try{E.current=!0;let o=new AbortController,{signal:i}=o;F.current=o;let a={signal:i,passive:!1};(n=p.current)==null||n.addEventListener("touchmove",V,a),document.addEventListener("mousemove",V,a);let f=(t instanceof MouseEvent?t.clientY:(r=(e=t.touches)==null?void 0:e[0])==null?void 0:r.clientY)||0,w=P.current;w.startY=f,w.yList=[[f,Date.now()]],w.touchScroll=m.current,w.isClick=!0,x()}catch(o){console.error("Error in initiateDragGesture:",o)}},$=j(t=>{let n=E.current,e=p.current.contains(t.target)||t.target===p.current;(n||e)&&t.cancelable&&(t.preventDefault(),s.length&&N(t))},[N]),wt=t=>{let n=m.current,e=n,r=t>0?-Z:Z,o=0;if(c){o=Math.abs(t/r);let i=t*o+.5*r*o*o;e=Math.round(n+i)}else if(n<0||n>s.length-1){let i=X(n,0,s.length-1),a=n-i;r=dt,o=Math.sqrt(Math.abs(a/r)),t=r*o,t=n>0?-t:t,e=i}else{o=Math.abs(t/r);let i=t*o+.5*r*o*o;e=Math.round(n+i),e=X(e,0,s.length-1);let a=e-n;o=Math.sqrt(Math.abs(a/r))}J(n,e,o,()=>{Y(m.current)}),Y(m.current)},tt=()=>{var t,n,e,r;try{(t=F.current)==null||t.abort(),F.current=null;let o=P.current;if(o.isClick){bt(o.startY);return}let i=o.yList,a=0;if(i.length>1){let f=i.length,[w,B]=(n=i[f-2])!=null?n:[0,0],[yt,Mt]=(e=i[f-1])!=null?e:[0,0],st=Mt-B;if(st>0){let at=(w-yt)/d*1e3/st,Tt=Et,St=at>0?1:-1;a=Math.min(Math.abs(at),Tt)*St}}m.current=(r=o.touchScroll)!=null?r:m.current,wt(a)}catch(o){console.error("Error in finalizeDragAndStartInertiaScroll:",o)}finally{E.current=!1}},q=j(t=>{if(!s.length)return;let n=E.current,e=p.current.contains(t.target)||t.target===p.current;(n||e)&&t.cancelable&&(t.preventDefault(),tt())},[tt]),et=t=>{t.preventDefault();let n=Date.now();if(n-_.current<100)return;let e=Math.sign(t.deltaY);e&&(_.current=n,Q(e))},nt=j(t=>{if(!s.length||!p.current)return;let n=E.current,e=p.current.contains(t.target)||t.target===p.current;(n||e)&&t.cancelable&&(t.preventDefault(),et(t))},[et]);return lt(()=>{let t=p.current;if(!t)return;let n=new AbortController,{signal:e}=n,r={signal:e,passive:!1};return t.addEventListener("touchstart",$,r),t.addEventListener("touchend",q,r),t.addEventListener("wheel",nt,r),document.addEventListener("mousedown",$,r),document.addEventListener("mouseup",q,r),()=>n.abort()},[q,$,nt]),lt(()=>{mt(O)},[O,g,s]),k.createElement("div",{ref:p,"data-rwp":!0,style:{height:ht}},k.createElement("ul",{ref:W,"data-rwp-options":!0},gt),k.createElement("div",{className:l==null?void 0:l.highlightWrapper,"data-rwp-highlight-wrapper":!0,"data-slot":"highlight-wrapper",style:{height:d,lineHeight:`${d}px`}},k.createElement("ul",{ref:z,"data-rwp-highlight-list":!0,style:{top:c?-d:void 0}},ft)))};export{Pt as WheelPicker,zt as WheelPickerWrapper};
1
+ "use client";import M from"react";import{useCallback as V,useEffect as ct,useMemo as P,useRef as T}from"react";import k from"react";function at(u){let g=k.useRef(u);return k.useEffect(()=>{g.current=u}),k.useMemo(()=>(...b)=>{var h;return(h=g.current)==null?void 0:h.call(g,...b)},[])}function kt({defaultProp:u,onChange:g}){let b=k.useState(u),[h]=b,c=k.useRef(h),v=at(g);return k.useEffect(()=>{c.current!==h&&(v(h),c.current=h)},[h,c,v]),b}function it({prop:u,defaultProp:g,onChange:b=()=>{}}){let[h,c]=kt({defaultProp:g,onChange:b}),v=u!==void 0,H=v?u:h,W=at(b),O=k.useCallback(l=>{if(v){let C=typeof l=="function"?l(u):l;C!==u&&W(C)}else c(l)},[v,u,c,W]);return[H,O]}var lt=.3,Mt=30,St=u=>Math.pow(u-1,3)+1,X=(u,g,b)=>Math.max(g,Math.min(u,b)),Ht=({className:u,children:g})=>M.createElement("div",{className:u,"data-rwp-wrapper":!0},g);function Ot({defaultValue:u,value:g,onValueChange:b,options:h,infinite:c=!1,visibleCount:v=20,dragSensitivity:H=3,scrollSensitivity:W=5,optionItemHeight:O=30,classNames:l}){var rt;let[z=(rt=h[0])==null?void 0:rt.value,C]=it({defaultProp:u,prop:g,onChange:b}),s=P(()=>{if(!c)return h;let t=[],e=Math.ceil(v/2);if(h.length===0)return t;for(;t.length<e;)t.push(...h);return t},[v,h,c]),d=O,G=d*.5,y=360/v,x=d/Math.tan(y*Math.PI/180),ut=Math.round(x*2+d*.25),E=v>>2,Z=H*10,ht=10,p=T(null),Y=T(null),U=T(null),m=T(0),K=T(0),S=T(!1),_=T(0),$=T({startY:0,yList:[],touchScroll:0,isClick:!0}),q=T(null),dt=P(()=>{let t=(n,r,o)=>M.createElement("li",{key:r,className:l==null?void 0:l.optionItem,"data-slot":"option-item","data-rwp-option":!0,"data-index":r,style:{top:-G,height:d,lineHeight:`${d}px`,transform:`rotateX(${o}deg) translateZ(${x}px)`,visibility:"hidden"}},n.label),e=s.map((n,r)=>t(n,r,-y*r));if(c)for(let n=0;n<E;++n){let r=-n-1,o=n+s.length;e.unshift(t(s[s.length-n-1],r,y*(n+1))),e.push(t(s[n],o,-y*o))}return e},[d,G,c,y,s,E,x,l==null?void 0:l.optionItem]),gt=P(()=>{let t=(n,r)=>M.createElement("li",{key:r,className:l==null?void 0:l.highlightItem,"data-slot":"highlight-item","data-rwp-highlight-item":!0,style:{height:d}},n.label),e=s.map((n,r)=>t(n,r));if(c){let n=s[0],r=s[s.length-1];e.unshift(t(r,"infinite-start")),e.push(t(n,"infinite-end"))}return e},[l==null?void 0:l.highlightItem,d,c,s]),ft=P(()=>{let t=0,e=Math.PI/180,n=[];for(let r=E-1;r>=-E+1;--r){let o=r*y,i=d*Math.cos(o*e),a=t;t+=i,n.push([a,t])}return n},[y,d,E]),B=t=>(t%s.length+s.length)%s.length,D=t=>{let e=c?B(t):t;if(Y.current){let n=`translateZ(${-x}px) rotateX(${y*e}deg)`;Y.current.style.transform=n,Y.current.childNodes.forEach(r=>{let o=r,i=Math.abs(Number(o.dataset.index)-e);o.style.visibility=i>E?"hidden":"visible"})}return U.current&&(U.current.style.transform=`translateY(${-e*d}px)`),e},A=()=>{cancelAnimationFrame(K.current)},J=(t,e,n,r)=>{if(t===e||n===0){D(t);return}let o=performance.now(),i=e-t,a=f=>{let w=(f-o)/1e3;if(w<n){let j=St(w/n);m.current=D(t+j*i),K.current=requestAnimationFrame(a)}else A(),m.current=D(e),r==null||r()};requestAnimationFrame(a)},R=t=>{let e=B(t)|0,n=c?e:Math.min(Math.max(e,0),s.length-1);if(!c&&n!==t)return;m.current=D(n);let r=s[m.current];C(r.value)},pt=t=>{let e=s.findIndex(n=>n.value===t);if(e===-1){console.error("Invalid value selected:",t);return}A(),R(e)},Q=t=>{let e=m.current,n=e+t;c?n=Math.round(n):n=X(Math.round(n),0,s.length-1);let r=Math.abs(n-e);if(r===0)return;let o=Math.sqrt(r/W);A(),J(e,n,o,()=>{R(m.current)})},mt=t=>{let e=p.current;if(!e){console.error("Container reference is not set.");return}let{top:n}=e.getBoundingClientRect(),r=t-n,o=ft.findIndex(([a,f])=>r>=a&&r<=f);if(o===-1){console.error("No item found for click position:",r);return}let i=(E-o-1)*-1;Q(i)},bt=t=>{var e,n;try{let r=(t instanceof MouseEvent?t.clientY:(n=(e=t.touches)==null?void 0:e[0])==null?void 0:n.clientY)||0,o=$.current;o.isClick&&Math.abs(r-o.startY)>5&&(o.isClick=!1),o.yList.push([r,Date.now()]),o.yList.length>5&&o.yList.shift();let i=(o.startY-r)/d,a=m.current+i;if(c)a=B(a);else{let f=s.length;a<0?a*=lt:a>f&&(a=f+(a-f)*lt)}o.touchScroll=D(a)}catch(r){console.error("Error in updateScrollDuringDrag:",r)}},N=t=>{var e;!S.current&&!((e=p.current)!=null&&e.contains(t.target))&&t.target!==p.current||(t.cancelable&&t.preventDefault(),s.length&&bt(t))},tt=t=>{var e,n,r;try{S.current=!0;let o=new AbortController,{signal:i}=o;q.current=o;let a={signal:i,passive:!1};(e=p.current)==null||e.addEventListener("touchmove",N,a),document.addEventListener("mousemove",N,a);let f=(t instanceof MouseEvent?t.clientY:(r=(n=t.touches)==null?void 0:n[0])==null?void 0:r.clientY)||0,w=$.current;w.startY=f,w.yList=[[f,Date.now()]],w.touchScroll=m.current,w.isClick=!0,A()}catch(o){console.error("Error in initiateDragGesture:",o)}},L=V(t=>{var r;let e=S.current,n=!!((r=p.current)!=null&&r.contains(t.target))||t.target===p.current;(e||n)&&t.cancelable&&(t.preventDefault(),s.length&&tt(t))},[tt]),vt=t=>{let e=m.current,n=e,r=t>0?-Z:Z,o=0;if(c){o=Math.abs(t/r);let i=t*o+.5*r*o*o;n=Math.round(e+i)}else if(e<0||e>s.length-1){let i=X(e,0,s.length-1),a=e-i;r=ht,o=Math.sqrt(Math.abs(a/r)),t=r*o,t=e>0?-t:t,n=i}else{o=Math.abs(t/r);let i=t*o+.5*r*o*o;n=Math.round(e+i),n=X(n,0,s.length-1);let a=n-e;o=Math.sqrt(Math.abs(a/r))}J(e,n,o,()=>{R(m.current)}),R(m.current)},et=()=>{var t,e,n,r;try{(t=q.current)==null||t.abort(),q.current=null;let o=$.current;if(o.isClick){mt(o.startY);return}let i=o.yList,a=0;if(i.length>1){let f=i.length,[w,j]=(e=i[f-2])!=null?e:[0,0],[wt,Tt]=(n=i[f-1])!=null?n:[0,0],ot=Tt-j;if(ot>0){let st=(w-wt)/d*1e3/ot,yt=Mt,Et=st>0?1:-1;a=Math.min(Math.abs(st),yt)*Et}}m.current=(r=o.touchScroll)!=null?r:m.current,vt(a)}catch(o){console.error("Error in finalizeDragAndStartInertiaScroll:",o)}finally{S.current=!1}},I=V(t=>{var r;if(!s.length)return;let e=S.current,n=!!((r=p.current)!=null&&r.contains(t.target))||t.target===p.current;(e||n)&&t.cancelable&&(t.preventDefault(),et())},[et]),nt=t=>{t.preventDefault();let e=Date.now();if(e-_.current<100)return;let n=Math.sign(t.deltaY);n&&(_.current=e,Q(n))},F=V(t=>{if(!s.length||!p.current)return;let e=S.current,n=p.current.contains(t.target)||t.target===p.current;(e||n)&&t.cancelable&&(t.preventDefault(),nt(t))},[nt]);return ct(()=>{let t=p.current;if(!t)return;let e={passive:!1};return t.addEventListener("touchstart",L,e),t.addEventListener("touchend",I,e),t.addEventListener("wheel",F,e),document.addEventListener("mousedown",L,e),document.addEventListener("mouseup",I,e),()=>{t.removeEventListener("touchstart",L),t.removeEventListener("touchend",I),t.removeEventListener("wheel",F),document.removeEventListener("mousedown",L),document.removeEventListener("mouseup",I)}},[I,L,F]),ct(()=>{pt(z)},[z,g,s]),M.createElement("div",{ref:p,"data-rwp":!0,style:{height:ut}},M.createElement("ul",{ref:Y,"data-rwp-options":!0},dt),M.createElement("div",{className:l==null?void 0:l.highlightWrapper,"data-rwp-highlight-wrapper":!0,"data-slot":"highlight-wrapper",style:{height:d,lineHeight:`${d}px`}},M.createElement("ul",{ref:U,"data-rwp-highlight-list":!0,style:{top:c?-d:void 0}},gt)))}export{Ot as WheelPicker,Ht as WheelPickerWrapper};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncdai/react-wheel-picker",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "iOS-like wheel picker for React with smooth inertia scrolling and infinite loop support.",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -55,6 +55,7 @@
55
55
  "url": "git+https://github.com/ncdai/react-wheel-picker.git",
56
56
  "directory": "packages/react-wheel-picker"
57
57
  },
58
+ "funding": "https://github.com/sponsors/ncdai",
58
59
  "bugs": {
59
60
  "url": "https://github.com/ncdai/react-wheel-picker/issues"
60
61
  },