@ncdai/react-wheel-picker 1.0.8 → 1.0.10
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 +2 -67
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -8,76 +8,11 @@ iOS-like wheel picker for React with smooth inertia scrolling and infinite loop
|
|
|
8
8
|
- 🎨 Unstyled components for complete style customization
|
|
9
9
|
- ⚡️ Easy installation via shadcn CLI
|
|
10
10
|
|
|
11
|
-
Check out the live demo: https://
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
To start using the library, install it in your project:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
pnpm add @ncdai/react-wheel-picker
|
|
19
|
-
# or
|
|
20
|
-
yarn add @ncdai/react-wheel-picker
|
|
21
|
-
# or
|
|
22
|
-
npm install @ncdai/react-wheel-picker
|
|
23
|
-
# or
|
|
24
|
-
bun add @ncdai/react-wheel-picker
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Add the core CSS to your app's entry point (e.g., `src/app/layout.tsx`, `src/main.tsx`, or `src/index.tsx`):
|
|
28
|
-
|
|
29
|
-
```tsx
|
|
30
|
-
import "@ncdai/react-wheel-picker/style.css";
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
> This CSS includes only basic layout. Use `classNames` to customize visuals (see below).
|
|
34
|
-
|
|
35
|
-
Use the component in your app:
|
|
36
|
-
|
|
37
|
-
```tsx
|
|
38
|
-
import {
|
|
39
|
-
WheelPicker,
|
|
40
|
-
WheelPickerWrapper,
|
|
41
|
-
type WheelPickerOption,
|
|
42
|
-
type WheelPickerClassNames,
|
|
43
|
-
} from "@ncdai/react-wheel-picker";
|
|
44
|
-
|
|
45
|
-
const options: WheelPickerOption[] = [
|
|
46
|
-
{
|
|
47
|
-
label: "React",
|
|
48
|
-
value: "react",
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
label: "Vue",
|
|
52
|
-
value: "vue",
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
label: "Angular",
|
|
56
|
-
value: "angular",
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
label: "Svelte",
|
|
60
|
-
value: "svelte",
|
|
61
|
-
},
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
const classNames: WheelPickerClassNames = {
|
|
65
|
-
optionItem: "text-zinc-400",
|
|
66
|
-
highlightWrapper: "bg-zinc-100 text-zinc-950",
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export function WheelPickerDemo() {
|
|
70
|
-
return (
|
|
71
|
-
<WheelPickerWrapper className="max-w-56 rounded-md border border-zinc-200 bg-white shadow-xs">
|
|
72
|
-
<WheelPicker options={options} classNames={classNames} />
|
|
73
|
-
</WheelPickerWrapper>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
```
|
|
11
|
+
Check out the live demo: https://react-wheel-picker.chanhdai.com
|
|
77
12
|
|
|
78
13
|
## Documentation
|
|
79
14
|
|
|
80
|
-
|
|
15
|
+
Please read the [documentation](https://react-wheel-picker.chanhdai.com/docs/getting-started) for setup and API usage.
|
|
81
16
|
|
|
82
17
|
## License
|
|
83
18
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";"use client";var wt=Object.create;var
|
|
1
|
+
"use strict";"use client";var wt=Object.create;var Y=Object.defineProperty;var yt=Object.getOwnPropertyDescriptor;var Et=Object.getOwnPropertyNames;var Mt=Object.getPrototypeOf,Tt=Object.prototype.hasOwnProperty;var Dt=(s,a)=>{for(var d in a)Y(s,d,{get:a[d],enumerable:!0})},rt=(s,a,d,f)=>{if(a&&typeof a=="object"||typeof a=="function")for(let i of Et(a))!Tt.call(s,i)&&i!==d&&Y(s,i,{get:()=>a[i],enumerable:!(f=yt(a,i))||f.enumerable});return s};var ot=(s,a,d)=>(d=s!=null?wt(Mt(s)):{},rt(a||!s||!s.__esModule?Y(d,"default",{value:s,enumerable:!0}):d,s)),St=s=>rt(Y({},"__esModule",{value:!0}),s);var Ct={};Dt(Ct,{WheelPicker:()=>xt,WheelPickerWrapper:()=>Wt});module.exports=St(Ct);var M=ot(require("react")),h=require("react");var E=ot(require("react"));function st(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 kt({defaultProp:s,onChange:a}){let d=E.default.useState(s),[f]=d,i=E.default.useRef(f),v=st(a);return E.default.useEffect(()=>{i.current!==f&&(v(f),i.current=f)},[f,i,v]),d}function at({prop:s,defaultProp:a,onChange:d=()=>{}}){let[f,i]=kt({defaultProp:a,onChange:d}),v=s!==void 0,A=v?s:f,g=st(d),I=E.default.useCallback(T=>{if(v){let p=typeof T=="function"?T(s):T;p!==s&&g(p)}else i(T)},[v,s,i,g]);return[A,I]}var ct=.3,It=30,Lt=s=>Math.pow(s-1,3)+1,$=(s,a,d)=>Math.max(a,Math.min(s,d)),Wt=({className:s,children:a})=>M.default.createElement("div",{className:s,"data-rwp-wrapper":!0},a),xt=({defaultValue:s,value:a,onValueChange:d,options:f,infinite:i=!1,visibleCount:v=20,dragSensitivity:A=3,classNames:g})=>{var N,tt;let[I=(tt=(N=f[0])==null?void 0:N.value)!=null?tt:"",T]=at({defaultProp:s,prop:a,onChange:d}),c=(0,h.useMemo)(()=>{if(!i)return f;let t=[],e=Math.ceil(v/2);if(f.length===0)return t;for(;t.length<e;)t.push(...f);return t},[v,f,i]),p=30,B=p*.5,D=360/v,L=p/Math.tan(D*Math.PI/180),it=Math.round(L*2+p*.25),R=v>>2,X=A*10,lt=10,b=(0,h.useRef)(null),W=(0,h.useRef)(null),H=(0,h.useRef)(null),m=(0,h.useRef)(0),j=(0,h.useRef)(0),S=(0,h.useRef)(!1),G=(0,h.useRef)(0),O=(0,h.useRef)({startY:0,yList:[]}),z=(0,h.useRef)(null),ut=(0,h.useMemo)(()=>{let t=(n,r,o)=>M.default.createElement("li",{key:r,className:g==null?void 0:g.optionItem,"data-rwp-option":!0,"data-index":r,style:{top:-B,height:p,lineHeight:`${p}px`,transform:`rotateX(${o}deg) translateZ(${L}px)`,visibility:"hidden"}},n.label),e=c.map((n,r)=>t(n,r,-D*r));if(i)for(let n=0;n<R;++n){let r=-n-1,o=n+c.length;e.unshift(t(c[c.length-n-1],r,D*(n+1))),e.push(t(c[n],o,-D*o))}return e},[B,i,D,c,R,L,g==null?void 0:g.optionItem]),ht=(0,h.useMemo)(()=>{let t=(n,r)=>M.default.createElement("li",{key:r,"data-slot":"highlight-item",className:g==null?void 0:g.highlightItem,style:{height:p}},n.label),e=c.map((n,r)=>t(n,r));if(i){let n=c[0],r=c[c.length-1];e.unshift(t(r,"infinite-start")),e.push(t(n,"infinite-end"))}return e},[g==null?void 0:g.highlightItem,i,c]),F=t=>(t%c.length+c.length)%c.length,k=t=>{let e=i?F(t):t;if(W.current){let n=`translateZ(${-L}px) rotateX(${D*e}deg)`;W.current.style.transform=n,W.current.childNodes.forEach(r=>{let o=r,u=Math.abs(Number(o.dataset.index)-e);o.style.visibility=u>R?"hidden":"visible"})}return H.current&&(H.current.style.transform=`translateY(${-e*p}px)`),e},x=()=>{cancelAnimationFrame(j.current)},Z=(t,e,n,r)=>{if(t===e||n===0){k(t);return}let o=performance.now(),u=e-t,l=w=>{let y=(w-o)/1e3;if(y<n){let P=Lt(y/n);m.current=k(t+P*u),j.current=requestAnimationFrame(l)}else x(),m.current=k(e),r==null||r()};requestAnimationFrame(l)},C=t=>{let e=F(t)|0,n=i?e:Math.min(Math.max(e,0),c.length-1);if(!i&&n!==t)return;m.current=k(n);let r=c[m.current];T(r.value)},dt=t=>{let e=c.findIndex(n=>n.value===t);if(e===-1){console.error("Invalid value selected:",t);return}x(),C(e)},ft=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=O.current;o.yList.push([r,Date.now()]),o.yList.length>5&&o.yList.shift();let u=(o.startY-r)/p,l=m.current+u;if(i)l=F(l);else{let w=c.length;l<0?l*=ct:l>w&&(l=w+(l-w)*ct)}o.touchScroll=k(l)}catch(r){console.error("Error in updateScrollDuringDrag:",r)}},K=t=>{!S.current&&!b.current.contains(t.target)&&t.target!==b.current||(t.cancelable&&t.preventDefault(),c.length&&ft(t))},_=t=>{var e,n,r;try{S.current=!0;let o=new AbortController,{signal:u}=o;z.current=o;let l={signal:u,passive:!1};(e=b.current)==null||e.addEventListener("touchmove",K,l),document.addEventListener("mousemove",K,l);let w=(t instanceof MouseEvent?t.clientY:(r=(n=t.touches)==null?void 0:n[0])==null?void 0:r.clientY)||0,y=O.current;y.startY=w,y.yList=[[w,Date.now()]],y.touchScroll=m.current,x()}catch(o){console.error("Error in initiateDragGesture:",o)}},U=(0,h.useCallback)(t=>{let e=S.current,n=b.current.contains(t.target)||t.target===b.current;(e||n)&&t.cancelable&&(t.preventDefault(),c.length&&_(t))},[_]),gt=t=>{let e=m.current,n=e,r=t>0?-X:X,o=0;if(i){o=Math.abs(t/r);let u=t*o+.5*r*o*o;n=Math.round(e+u)}else if(e<0||e>c.length-1){let u=$(e,0,c.length-1),l=e-u;r=lt,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=$(n,0,c.length-1);let l=n-e;o=Math.sqrt(Math.abs(l/r))}Z(e,n,o,()=>{C(m.current)}),C(m.current)},J=()=>{var t,e,n,r;try{(t=z.current)==null||t.abort(),z.current=null;let o=O.current,u=o.yList,l=0;if(u.length>1){let w=u.length,[y,P]=(e=u[w-2])!=null?e:[0,0],[pt,mt]=(n=u[w-1])!=null?n:[0,0],et=mt-P;if(et>0){let nt=(y-pt)/p*1e3/et,bt=It,vt=nt>0?1:-1;l=Math.min(Math.abs(nt),bt)*vt}}m.current=(r=o.touchScroll)!=null?r:m.current,gt(l)}catch(o){console.error("Error in finalizeDragAndStartInertiaScroll:",o)}finally{S.current=!1}},q=(0,h.useCallback)(t=>{if(!c.length)return;let e=S.current,n=b.current.contains(t.target)||t.target===b.current;(e||n)&&t.cancelable&&(t.preventDefault(),J())},[J]),Q=t=>{t.preventDefault();let e=Date.now();if(e-G.current<100)return;let n=Math.sign(t.deltaY);if(!n)return;G.current=e;let r=m.current,o=r+n;i?o=Math.round(o):o=$(Math.round(o),0,c.length-1);let u=Math.abs(o-r);if(u===0)return;let l=Math.sqrt(u/5);x(),Z(r,o,l,()=>{C(m.current)})},V=(0,h.useCallback)(t=>{if(!c.length||!b.current)return;let e=S.current,n=b.current.contains(t.target)||t.target===b.current;(e||n)&&t.cancelable&&(t.preventDefault(),Q(t))},[Q]);return(0,h.useEffect)(()=>{let t=b.current;if(!t)return;let e=new AbortController,{signal:n}=e,r={signal:n,passive:!1};return t.addEventListener("touchstart",U,r),t.addEventListener("touchend",q,r),t.addEventListener("wheel",V,r),document.addEventListener("mousedown",U,r),document.addEventListener("mouseup",q,r),()=>e.abort()},[q,U,V]),(0,h.useEffect)(()=>{dt(I)},[I,a]),M.default.createElement("div",{ref:b,"data-rwp":!0,style:{height:it}},M.default.createElement("ul",{ref:W,"data-rwp-options":!0},ut),M.default.createElement("div",{className:g==null?void 0:g.highlightWrapper,"data-rwp-highlight-wrapper":!0,style:{height:p,lineHeight:p+"px"}},M.default.createElement("ul",{ref:H,"data-rwp-highlight-list":!0,style:{top:i?-p:void 0}},ht)))};0&&(module.exports={WheelPicker,WheelPickerWrapper});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import M from"react";import{useCallback as
|
|
1
|
+
"use client";import M from"react";import{useCallback as P,useEffect as at,useMemo as $,useRef as w}from"react";import E from"react";function ot(l){let d=E.useRef(l);return E.useEffect(()=>{d.current=l}),E.useMemo(()=>(...m)=>{var h;return(h=d.current)==null?void 0:h.call(d,...m)},[])}function wt({defaultProp:l,onChange:d}){let m=E.useState(l),[h]=m,i=E.useRef(h),b=ot(d);return E.useEffect(()=>{i.current!==h&&(b(h),i.current=h)},[h,i,b]),m}function st({prop:l,defaultProp:d,onChange:m=()=>{}}){let[h,i]=wt({defaultProp:d,onChange:m}),b=l!==void 0,Y=b?l:h,u=ot(m),I=E.useCallback(T=>{if(b){let f=typeof T=="function"?T(l):T;f!==l&&u(f)}else i(T)},[b,l,i,u]);return[Y,I]}var ct=.3,yt=30,Et=l=>Math.pow(l-1,3)+1,B=(l,d,m)=>Math.max(d,Math.min(l,m)),Yt=({className:l,children:d})=>M.createElement("div",{className:l,"data-rwp-wrapper":!0},d),At=({defaultValue:l,value:d,onValueChange:m,options:h,infinite:i=!1,visibleCount:b=20,dragSensitivity:Y=3,classNames:u})=>{var tt,et;let[I=(et=(tt=h[0])==null?void 0:tt.value)!=null?et:"",T]=st({defaultProp:l,prop:d,onChange:m}),s=$(()=>{if(!i)return h;let t=[],e=Math.ceil(b/2);if(h.length===0)return t;for(;t.length<e;)t.push(...h);return t},[b,h,i]),f=30,X=f*.5,D=360/b,L=f/Math.tan(D*Math.PI/180),it=Math.round(L*2+f*.25),A=b>>2,j=Y*10,lt=10,p=w(null),W=w(null),R=w(null),g=w(0),G=w(0),S=w(!1),Z=w(0),H=w({startY:0,yList:[]}),O=w(null),ut=$(()=>{let t=(n,r,o)=>M.createElement("li",{key:r,className:u==null?void 0:u.optionItem,"data-rwp-option":!0,"data-index":r,style:{top:-X,height:f,lineHeight:`${f}px`,transform:`rotateX(${o}deg) translateZ(${L}px)`,visibility:"hidden"}},n.label),e=s.map((n,r)=>t(n,r,-D*r));if(i)for(let n=0;n<A;++n){let r=-n-1,o=n+s.length;e.unshift(t(s[s.length-n-1],r,D*(n+1))),e.push(t(s[n],o,-D*o))}return e},[X,i,D,s,A,L,u==null?void 0:u.optionItem]),ht=$(()=>{let t=(n,r)=>M.createElement("li",{key:r,"data-slot":"highlight-item",className:u==null?void 0:u.highlightItem,style:{height:f}},n.label),e=s.map((n,r)=>t(n,r));if(i){let n=s[0],r=s[s.length-1];e.unshift(t(r,"infinite-start")),e.push(t(n,"infinite-end"))}return e},[u==null?void 0:u.highlightItem,i,s]),z=t=>(t%s.length+s.length)%s.length,k=t=>{let e=i?z(t):t;if(W.current){let n=`translateZ(${-L}px) rotateX(${D*e}deg)`;W.current.style.transform=n,W.current.childNodes.forEach(r=>{let o=r,c=Math.abs(Number(o.dataset.index)-e);o.style.visibility=c>A?"hidden":"visible"})}return R.current&&(R.current.style.transform=`translateY(${-e*f}px)`),e},x=()=>{cancelAnimationFrame(G.current)},K=(t,e,n,r)=>{if(t===e||n===0){k(t);return}let o=performance.now(),c=e-t,a=v=>{let y=(v-o)/1e3;if(y<n){let q=Et(y/n);g.current=k(t+q*c),G.current=requestAnimationFrame(a)}else x(),g.current=k(e),r==null||r()};requestAnimationFrame(a)},C=t=>{let e=z(t)|0,n=i?e:Math.min(Math.max(e,0),s.length-1);if(!i&&n!==t)return;g.current=k(n);let r=s[g.current];T(r.value)},dt=t=>{let e=s.findIndex(n=>n.value===t);if(e===-1){console.error("Invalid value selected:",t);return}x(),C(e)},ft=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=H.current;o.yList.push([r,Date.now()]),o.yList.length>5&&o.yList.shift();let c=(o.startY-r)/f,a=g.current+c;if(i)a=z(a);else{let v=s.length;a<0?a*=ct:a>v&&(a=v+(a-v)*ct)}o.touchScroll=k(a)}catch(r){console.error("Error in updateScrollDuringDrag:",r)}},_=t=>{!S.current&&!p.current.contains(t.target)&&t.target!==p.current||(t.cancelable&&t.preventDefault(),s.length&&ft(t))},J=t=>{var e,n,r;try{S.current=!0;let o=new AbortController,{signal:c}=o;O.current=o;let a={signal:c,passive:!1};(e=p.current)==null||e.addEventListener("touchmove",_,a),document.addEventListener("mousemove",_,a);let v=(t instanceof MouseEvent?t.clientY:(r=(n=t.touches)==null?void 0:n[0])==null?void 0:r.clientY)||0,y=H.current;y.startY=v,y.yList=[[v,Date.now()]],y.touchScroll=g.current,x()}catch(o){console.error("Error in initiateDragGesture:",o)}},F=P(t=>{let e=S.current,n=p.current.contains(t.target)||t.target===p.current;(e||n)&&t.cancelable&&(t.preventDefault(),s.length&&J(t))},[J]),gt=t=>{let e=g.current,n=e,r=t>0?-j:j,o=0;if(i){o=Math.abs(t/r);let c=t*o+.5*r*o*o;n=Math.round(e+c)}else if(e<0||e>s.length-1){let c=B(e,0,s.length-1),a=e-c;r=lt,o=Math.sqrt(Math.abs(a/r)),t=r*o,t=e>0?-t:t,n=c}else{o=Math.abs(t/r);let c=t*o+.5*r*o*o;n=Math.round(e+c),n=B(n,0,s.length-1);let a=n-e;o=Math.sqrt(Math.abs(a/r))}K(e,n,o,()=>{C(g.current)}),C(g.current)},Q=()=>{var t,e,n,r;try{(t=O.current)==null||t.abort(),O.current=null;let o=H.current,c=o.yList,a=0;if(c.length>1){let v=c.length,[y,q]=(e=c[v-2])!=null?e:[0,0],[pt,mt]=(n=c[v-1])!=null?n:[0,0],nt=mt-q;if(nt>0){let rt=(y-pt)/f*1e3/nt,bt=yt,vt=rt>0?1:-1;a=Math.min(Math.abs(rt),bt)*vt}}g.current=(r=o.touchScroll)!=null?r:g.current,gt(a)}catch(o){console.error("Error in finalizeDragAndStartInertiaScroll:",o)}finally{S.current=!1}},U=P(t=>{if(!s.length)return;let e=S.current,n=p.current.contains(t.target)||t.target===p.current;(e||n)&&t.cancelable&&(t.preventDefault(),Q())},[Q]),V=t=>{t.preventDefault();let e=Date.now();if(e-Z.current<100)return;let n=Math.sign(t.deltaY);if(!n)return;Z.current=e;let r=g.current,o=r+n;i?o=Math.round(o):o=B(Math.round(o),0,s.length-1);let c=Math.abs(o-r);if(c===0)return;let a=Math.sqrt(c/5);x(),K(r,o,a,()=>{C(g.current)})},N=P(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(),V(t))},[V]);return at(()=>{let t=p.current;if(!t)return;let e=new AbortController,{signal:n}=e,r={signal:n,passive:!1};return t.addEventListener("touchstart",F,r),t.addEventListener("touchend",U,r),t.addEventListener("wheel",N,r),document.addEventListener("mousedown",F,r),document.addEventListener("mouseup",U,r),()=>e.abort()},[U,F,N]),at(()=>{dt(I)},[I,d]),M.createElement("div",{ref:p,"data-rwp":!0,style:{height:it}},M.createElement("ul",{ref:W,"data-rwp-options":!0},ut),M.createElement("div",{className:u==null?void 0:u.highlightWrapper,"data-rwp-highlight-wrapper":!0,style:{height:f,lineHeight:f+"px"}},M.createElement("ul",{ref:R,"data-rwp-highlight-list":!0,style:{top:i?-f:void 0}},ht)))};export{At as WheelPicker,Yt as WheelPickerWrapper};
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ncdai/react-wheel-picker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "iOS-like wheel picker for React with smooth inertia scrolling and infinite loop support.",
|
|
5
5
|
"publishConfig": {
|
|
6
|
-
"access": "public"
|
|
6
|
+
"access": "public",
|
|
7
|
+
"provenance": true
|
|
7
8
|
},
|
|
8
9
|
"type": "commonjs",
|
|
9
10
|
"main": "./dist/index.js",
|