@ncdai/react-swipe-actions 0.2.0 → 0.3.0

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
@@ -5,6 +5,7 @@ Swipe a row in a list to reveal actions on the left or right.
5
5
  - Composable parts, no config props.
6
6
  - Polymorphic `render` prop, so a row can be any element you want.
7
7
  - Only one row open at a time.
8
+ - Full swipe runs the outermost action, the way Mail does on iOS.
8
9
  - Keyboard, `Escape` and click-outside dismissal.
9
10
  - Unstyled, with no CSS to import and no runtime dependencies.
10
11
 
@@ -16,102 +17,102 @@ Swipe a row in a list to reveal actions on the left or right.
16
17
  npm i @ncdai/react-swipe-actions motion
17
18
  ```
18
19
 
19
- `react` and `motion` are peer dependencies.
20
-
21
20
  ## Usage
22
21
 
22
+ Paste this in and swipe the row. Classes are Tailwind; every part takes `style`
23
+ too.
24
+
23
25
  ```tsx
26
+ "use client"
27
+
24
28
  import {
25
29
  SwipeAction,
30
+ SwipeActionContent,
26
31
  SwipeActions,
27
32
  SwipeContent,
28
33
  SwipeItem,
29
34
  SwipeRoot,
30
35
  } from "@ncdai/react-swipe-actions"
31
36
 
32
- function Inbox({ mails }: { mails: Mail[] }) {
37
+ export function Example() {
33
38
  return (
34
- <SwipeRoot render={<ul />}>
35
- {mails.map((mail) => (
36
- <SwipeItem key={mail.id} render={<li />}>
37
- <SwipeActions side="left">
38
- <SwipeAction onClick={() => archive(mail.id)}>Archive</SwipeAction>
39
- </SwipeActions>
40
-
41
- <SwipeActions side="right">
42
- <SwipeAction onClick={() => remove(mail.id)}>Delete</SwipeAction>
43
- </SwipeActions>
44
-
45
- <SwipeContent>{mail.subject}</SwipeContent>
46
- </SwipeItem>
47
- ))}
39
+ <SwipeRoot className="max-w-md overflow-clip rounded-xl border border-neutral-200 dark:border-neutral-800">
40
+ <SwipeItem>
41
+ <SwipeActions side="right" fullSwipe>
42
+ <SwipeAction
43
+ className="bg-amber-500 text-sm text-white"
44
+ onClick={() => alert("Flagged")}
45
+ >
46
+ <SwipeActionContent className="w-20 items-center justify-center">
47
+ Flag
48
+ </SwipeActionContent>
49
+ </SwipeAction>
50
+
51
+ <SwipeAction
52
+ className="bg-red-600 text-sm text-white"
53
+ onClick={() => alert("Deleted")}
54
+ >
55
+ <SwipeActionContent className="w-20 items-center justify-center">
56
+ Delete
57
+ </SwipeActionContent>
58
+ </SwipeAction>
59
+ </SwipeActions>
60
+
61
+ <SwipeContent className="bg-white p-4 text-neutral-950 dark:bg-neutral-950 dark:text-neutral-50">
62
+ Namespaced registries
63
+ </SwipeContent>
64
+ </SwipeItem>
48
65
  </SwipeRoot>
49
66
  )
50
67
  }
51
68
  ```
52
69
 
53
- `SwipeRoot` is optional. It only makes sibling rows close one another, so a
54
- lone `SwipeItem` works on its own.
70
+ `SwipeRoot` is optional, it only makes sibling rows close one another. An item
71
+ takes one `SwipeActions` per side, and `render` swaps any part's element, so a
72
+ list is `<SwipeRoot render={<ul />}>` around `<SwipeItem render={<li />}>`.
55
73
 
56
74
  ## Styling
57
75
 
58
- The package positions the strips behind the content and makes the content
59
- draggable. Everything else is yours. Two things it cannot do for you:
60
-
61
- - **Give `SwipeContent` an opaque background.** It is what hides the strips
62
- while the row is closed.
63
- - **Give `SwipeAction` a width.** The strip is measured to decide how far the
64
- row opens, so zero-width actions never appear.
76
+ Everything is yours to style, with three rules:
65
77
 
66
- Enough to get a usable row, with Tailwind:
67
-
68
- ```tsx
69
- <SwipeRoot render={<ul />} className="divide-y border-y">
70
- <SwipeItem render={<li />}>
71
- <SwipeActions side="right">
72
- <SwipeAction
73
- className="w-20 bg-red-600 text-sm text-white"
74
- onClick={() => remove(mail.id)}
75
- >
76
- Delete
77
- </SwipeAction>
78
- </SwipeActions>
79
-
80
- <SwipeContent className="bg-white p-4 dark:bg-zinc-950">
81
- {mail.subject}
82
- </SwipeContent>
83
- </SwipeItem>
84
- </SwipeRoot>
85
- ```
78
+ - **Paint on `SwipeAction`, layout on `SwipeActionContent`.** The action covers
79
+ the whole row, the content is the slice you see. That is what lets a full
80
+ swipe flood it.
81
+ - **`SwipeContent` needs an opaque background.** It hides the actions while the
82
+ row is closed.
83
+ - **`SwipeActionContent` needs a width.** It is measured to decide how far the
84
+ row opens, so a zero-width one never shows.
86
85
 
87
86
  ## Parts
88
87
 
89
- | Part | Renders | `render` prop |
90
- | -------------- | ------------ | ------------- |
91
- | `SwipeRoot` | `div` | yes |
92
- | `SwipeItem` | `div` | yes |
93
- | `SwipeActions` | `div` | yes |
94
- | `SwipeAction` | `button` | yes |
95
- | `SwipeContent` | `motion.div` | no |
88
+ | Part | Renders | `render` prop |
89
+ | -------------------- | ------------ | ------------- |
90
+ | `SwipeRoot` | `div` | yes |
91
+ | `SwipeItem` | `div` | yes |
92
+ | `SwipeActions` | `div` | yes |
93
+ | `SwipeAction` | `button` | yes |
94
+ | `SwipeActionContent` | `span` | yes |
95
+ | `SwipeContent` | `motion.div` | no |
96
96
 
97
- `SwipeActions`, `SwipeAction` and `SwipeContent` must live inside a
98
- `SwipeItem`. Every part forwards `ref` and passes unknown props through.
97
+ Every part forwards `ref` and passes unknown props through.
99
98
 
100
99
  ### SwipeItem
101
100
 
102
- | Prop | Default | Description |
103
- | ---------------- | ------- | --------------------------------------------------------------------------------------- |
104
- | `threshold` | `0.5` | Fraction of the strip the drag must cross to snap open |
105
- | `velocityFactor` | `0.2` | Seconds of release velocity added to the position, so a flick opens without a full drag |
106
- | `disabled` | `false` | Turns the gesture off |
107
- | `closeOnScroll` | `false` | Close on any scroll on the page |
108
- | `onOpenChange` | | Called with `"closed"`, `"left"` or `"right"` |
101
+ | Prop | Default | Description |
102
+ | -------------------- | ------- | --------------------------------------------------------------------------------------- |
103
+ | `threshold` | `0.5` | Fraction of the strip the drag must cross to snap open |
104
+ | `velocityFactor` | `0.2` | Seconds of release velocity added to the position, so a flick opens without a full drag |
105
+ | `disabled` | `false` | Turns the gesture off |
106
+ | `closeOnScroll` | `false` | Close on any scroll on the page |
107
+ | `fullSwipeThreshold` | `0.5` | Fraction of the row width the drag must cross to arm a `fullSwipe` strip |
108
+ | `onOpenChange` | | Called with `"closed"`, `"left"` or `"right"` |
109
109
 
110
110
  ### SwipeActions
111
111
 
112
- | Prop | Description |
113
- | ------ | ------------------------------- |
114
- | `side` | `"left"` or `"right"`. Required |
112
+ | Prop | Default | Description |
113
+ | ----------- | ------- | --------------------------------------------------------------- |
114
+ | `side` | | `"left"` or `"right"`. Required |
115
+ | `fullSwipe` | `false` | Let a drag across the row run the outermost action of the strip |
115
116
 
116
117
  ### SwipeAction
117
118
 
@@ -123,21 +124,22 @@ Enough to get a usable row, with Tailwind:
123
124
 
124
125
  Style against these rather than tracking state yourself.
125
126
 
126
- | Attribute | On | Value |
127
- | --------------- | --------------------------- | ---------------------------------------------- |
128
- | `data-state` | `SwipeItem` | `closed`, `left`, `right` |
129
- | `data-disabled` | `SwipeItem` | present when disabled |
130
- | `data-dragging` | `SwipeItem`, `SwipeContent` | present while dragging |
131
- | `data-side` | `SwipeActions` | `left`, `right` |
132
- | `data-slot` | every part | `swipe-root`, `swipe-item`, `swipe-actions`, |
127
+ | Attribute | On | Value |
128
+ | --------------- | ----------------------------- | ---------------------------------------------- |
129
+ | `data-state` | `SwipeItem` | `closed`, `left`, `right` |
130
+ | `data-disabled` | `SwipeItem` | present when disabled |
131
+ | `data-dragging` | `SwipeItem`, `SwipeContent` | present while dragging |
132
+ | `data-side` | `SwipeActions` | `left`, `right` |
133
+ | `data-armed` | `SwipeActions`, `SwipeAction` | present while a full swipe is armed |
134
+ | `data-slot` | every part | `swipe-root`, `swipe-item`, `swipe-actions`, … |
133
135
 
134
136
  ## Accessibility
135
137
 
136
- - Closed strips are `inert`, so their buttons stay out of the tab order, the
137
- accessibility tree and hit testing.
138
+ - Closed actions are `inert`: out of the tab order, the accessibility tree and
139
+ hit testing. Only the content is a hit target, never the rest of the action.
138
140
  - With focus inside a row, `ArrowLeft` and `ArrowRight` move it one step in that
139
- direction and `Escape` closes it. Focusable row content is what carries focus
140
- there.
141
+ direction and `Escape` closes it. The row needs focusable content to receive
142
+ focus.
141
143
  - Under `prefers-reduced-motion` the row snaps into place instead of animating.
142
144
 
143
145
  ## License
package/dist/index.d.mts CHANGED
@@ -52,23 +52,30 @@ type SwipeItemProps = UseRenderComponentProps<"div", SwipeItemState> & {
52
52
  declare function SwipeItem({ render, threshold, velocityFactor, fullSwipeThreshold, disabled, closeOnScroll, onOpenChange, ...props }: SwipeItemProps): React.JSX.Element;
53
53
  type SwipeActionsProps = UseRenderComponentProps<"div"> & {
54
54
  side: SwipeSide;
55
+ /**
56
+ * Let a drag past `fullSwipeThreshold` run the outermost action, the way Mail
57
+ * does on iOS. The takeover works by that action covering the others, so it
58
+ * is always the outermost one, as it is on the platform.
59
+ * @defaultValue false
60
+ */
61
+ fullSwipe?: boolean;
55
62
  };
56
- declare function SwipeActions({ render, side, ...props }: SwipeActionsProps): React.JSX.Element;
63
+ declare function SwipeActions({ render, side, fullSwipe, ...props }: SwipeActionsProps): React.JSX.Element;
57
64
  type SwipeActionProps = UseRenderComponentProps<"button"> & {
58
65
  /**
59
66
  * Close the item once the click handler has run.
60
67
  * @defaultValue true
61
68
  */
62
69
  closeOnClick?: boolean;
63
- /**
64
- * Run this action when the item is dragged past `fullSwipeThreshold`, the way
65
- * Mail does on iOS. One action per side; it takes over the strip once armed.
66
- * @defaultValue false
67
- */
68
- fullSwipe?: boolean;
69
70
  };
70
- declare function SwipeAction({ render, closeOnClick, fullSwipe, ...props }: SwipeActionProps): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
71
+ declare function SwipeAction({ render, closeOnClick, ...props }: SwipeActionProps): React.JSX.Element;
72
+ type SwipeActionContentProps = UseRenderComponentProps<"span">;
73
+ /**
74
+ * The visible slice of an action. Its width is what the item measures, so the
75
+ * action it sits in can cover the row without changing how far the row opens.
76
+ */
77
+ declare function SwipeActionContent({ render, ...props }: SwipeActionContentProps): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
71
78
  type SwipeContentProps = HTMLMotionProps<"div">;
72
79
  declare function SwipeContent({ style, ...props }: SwipeContentProps): React.JSX.Element;
73
80
 
74
- export { SwipeAction, type SwipeActionProps, SwipeActions, type SwipeActionsProps, SwipeContent, type SwipeContentProps, SwipeItem, type SwipeItemProps, type SwipeItemState, SwipeRoot, type SwipeRootProps, type SwipeSide, type SwipeState };
81
+ export { SwipeAction, SwipeActionContent, type SwipeActionContentProps, type SwipeActionProps, SwipeActions, type SwipeActionsProps, SwipeContent, type SwipeContentProps, SwipeItem, type SwipeItemProps, type SwipeItemState, SwipeRoot, type SwipeRootProps, type SwipeSide, type SwipeState };
package/dist/index.d.ts CHANGED
@@ -52,23 +52,30 @@ type SwipeItemProps = UseRenderComponentProps<"div", SwipeItemState> & {
52
52
  declare function SwipeItem({ render, threshold, velocityFactor, fullSwipeThreshold, disabled, closeOnScroll, onOpenChange, ...props }: SwipeItemProps): React.JSX.Element;
53
53
  type SwipeActionsProps = UseRenderComponentProps<"div"> & {
54
54
  side: SwipeSide;
55
+ /**
56
+ * Let a drag past `fullSwipeThreshold` run the outermost action, the way Mail
57
+ * does on iOS. The takeover works by that action covering the others, so it
58
+ * is always the outermost one, as it is on the platform.
59
+ * @defaultValue false
60
+ */
61
+ fullSwipe?: boolean;
55
62
  };
56
- declare function SwipeActions({ render, side, ...props }: SwipeActionsProps): React.JSX.Element;
63
+ declare function SwipeActions({ render, side, fullSwipe, ...props }: SwipeActionsProps): React.JSX.Element;
57
64
  type SwipeActionProps = UseRenderComponentProps<"button"> & {
58
65
  /**
59
66
  * Close the item once the click handler has run.
60
67
  * @defaultValue true
61
68
  */
62
69
  closeOnClick?: boolean;
63
- /**
64
- * Run this action when the item is dragged past `fullSwipeThreshold`, the way
65
- * Mail does on iOS. One action per side; it takes over the strip once armed.
66
- * @defaultValue false
67
- */
68
- fullSwipe?: boolean;
69
70
  };
70
- declare function SwipeAction({ render, closeOnClick, fullSwipe, ...props }: SwipeActionProps): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
71
+ declare function SwipeAction({ render, closeOnClick, ...props }: SwipeActionProps): React.JSX.Element;
72
+ type SwipeActionContentProps = UseRenderComponentProps<"span">;
73
+ /**
74
+ * The visible slice of an action. Its width is what the item measures, so the
75
+ * action it sits in can cover the row without changing how far the row opens.
76
+ */
77
+ declare function SwipeActionContent({ render, ...props }: SwipeActionContentProps): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
71
78
  type SwipeContentProps = HTMLMotionProps<"div">;
72
79
  declare function SwipeContent({ style, ...props }: SwipeContentProps): React.JSX.Element;
73
80
 
74
- export { SwipeAction, type SwipeActionProps, SwipeActions, type SwipeActionsProps, SwipeContent, type SwipeContentProps, SwipeItem, type SwipeItemProps, type SwipeItemState, SwipeRoot, type SwipeRootProps, type SwipeSide, type SwipeState };
81
+ export { SwipeAction, SwipeActionContent, type SwipeActionContentProps, type SwipeActionProps, SwipeActions, type SwipeActionsProps, SwipeContent, type SwipeContentProps, SwipeItem, type SwipeItemProps, type SwipeItemState, SwipeRoot, type SwipeRootProps, type SwipeSide, type SwipeState };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";"use client";var Pe=Object.create;var F=Object.defineProperty,Te=Object.defineProperties,xe=Object.getOwnPropertyDescriptor,ke=Object.getOwnPropertyDescriptors,Ae=Object.getOwnPropertyNames,B=Object.getOwnPropertySymbols,De=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty,se=Object.prototype.propertyIsEnumerable;var ie=(t,e,n)=>e in t?F(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,g=(t,e)=>{for(var n in e||(e={}))Y.call(e,n)&&ie(t,n,e[n]);if(B)for(var n of B(e))se.call(e,n)&&ie(t,n,e[n]);return t},C=(t,e)=>Te(t,ke(e));var A=(t,e)=>{var n={};for(var r in t)Y.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&B)for(var r of B(t))e.indexOf(r)<0&&se.call(t,r)&&(n[r]=t[r]);return n};var Me=(t,e)=>{for(var n in e)F(t,n,{get:e[n],enumerable:!0})},ae=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ae(e))!Y.call(t,i)&&i!==n&&F(t,i,{get:()=>e[i],enumerable:!(r=xe(e,i))||r.enumerable});return t};var ce=(t,e,n)=>(n=t!=null?Pe(De(t)):{},ae(e||!t||!t.__esModule?F(n,"default",{value:t,enumerable:!0}):n,t)),We=t=>ae(F({},"__esModule",{value:!0}),t);var Ke={};Me(Ke,{SwipeAction:()=>ge,SwipeActions:()=>me,SwipeContent:()=>ye,SwipeItem:()=>we,SwipeRoot:()=>fe});module.exports=We(Ke);var o=ce(require("react")),E=require("motion/react");var O=ce(require("react"));function K({defaultTagName:t,props:e,render:n,state:r={},stateAttributesMapping:i}){let a=D(Ie(r,i),e);if(!n)return O.createElement(t,a);if(typeof n=="function")return n(a,r);if(!O.isValidElement(n))return null;let l=n.props,S=D(a,l),R=C(g({},S),{ref:le(a.ref,l.ref)});return O.cloneElement(n,R)}function D(...t){let e={};for(let n of t){if(!n)continue;let r=n;for(let i of Object.keys(r)){let a=r[i];if(a===void 0)continue;let l=e[i];i==="className"?e[i]=[l,a].filter(Boolean).join(" "):i==="style"?e[i]=g(g({},l),a):i==="ref"?e[i]=le(l,a):He(i)&&typeof l=="function"&&typeof a=="function"?e[i]=Le(a,l):e[i]=a}}return e}function Ie(t,e){var r;let n={};for(let i of Object.keys(t)){let a=t[i],l=(r=e==null?void 0:e[i])==null?void 0:r.call(e,a);if(l){Object.assign(n,l);continue}if(i==="slot"){n["data-slot"]=a;continue}let S=`data-${String(i).replace(/[A-Z]/g,R=>`-${R.toLowerCase()}`)}`;typeof a=="boolean"?n[S]=a?"":void 0:a!=null&&(n[S]=String(a))}return n}function Le(t,e){return function(r){t(r),r.defaultPrevented||e(r)}}function He(t){return/^on[A-Z]/.test(t)}function le(...t){let e=t.filter(Boolean);if(e.length!==0)return n=>{for(let r of e)typeof r=="function"?r(n):r&&(r.current=n)}}var z=require("react/jsx-runtime"),Ne={position:"relative",isolation:"isolate",overflow:"clip"},Oe={position:"absolute",top:0,bottom:0,zIndex:0,display:"flex"},Ve={position:"relative",zIndex:1},de={type:"spring",stiffness:500,damping:45,mass:.8},Ue=C(g({},de),{damping:36}),_e=4,ue={duration:.18,ease:[.32,.72,0,1]},pe=o.createContext(null);function fe(n){var r=n,{render:t}=r,e=A(r,["render"]);let i=o.useRef(new Map),a=o.useMemo(()=>({register(S,R){return i.current.set(S,R),()=>{i.current.delete(S)}},notifyOpen(S){for(let[R,y]of i.current)R!==S&&y()}}),[]),l=K({defaultTagName:"div",render:t,props:D({"data-slot":"swipe-root"},e)});return(0,z.jsx)(pe.Provider,{value:a,children:l})}var Se=o.createContext(null),Re=o.createContext(null);function Fe(){let t=o.useContext(Re);if(!t)throw new Error("SwipeAction must be used within SwipeActions");return t}function $(){let t=o.useContext(Se);if(!t)throw new Error("Swipe parts must be used within SwipeItem");return t}function we(R){var y=R,{render:t,threshold:e=.5,velocityFactor:n=.2,fullSwipeThreshold:r=.5,disabled:i=!1,closeOnScroll:a=!1,onOpenChange:l}=y,S=A(y,["render","threshold","velocityFactor","fullSwipeThreshold","disabled","closeOnScroll","onOpenChange"]);let w=o.useId(),c=o.useContext(pe),v=(0,E.useReducedMotion)(),x=o.useRef(null),[f,d]=o.useState({left:0,right:0}),[m,h]=o.useState(0),[k,G]=o.useState(null),M=o.useRef(null),V=o.useRef({}),[Z,q]=o.useState({left:!1,right:!1}),[W,ve]=o.useState("closed"),[j,J]=o.useState(!1),I=o.useRef("closed"),L=o.useRef(!1),b=(0,E.useMotionValue)(0),Q=o.useCallback((s,u)=>{d(p=>p[s]===u?p:C(g({},p),{[s]:u}))},[]),X=o.useCallback((s,u)=>(V.current[s]=u,q(p=>C(g({},p),{[s]:!0})),()=>{delete V.current[s],q(p=>C(g({},p),{[s]:!1}))}),[]),H=o.useCallback(s=>{M.current!==s&&(M.current=s,G(s))},[]);o.useEffect(()=>{let s=x.current;if(!s)return;let u=new ResizeObserver(()=>h(s.offsetWidth));return u.observe(s),()=>u.disconnect()},[]);let P=o.useCallback((s,u)=>{let p=s==="left"?f.left:s==="right"?-f.right:0;(0,E.animate)(b,p,v?{duration:0}:u===void 0?de:C(g({},Ue),{velocity:u})),s!=="closed"&&(c==null||c.notifyOpen(w)),I.current!==s&&(I.current=s,ve(s),l==null||l(s))},[f,b,v,c,w,l]),N=o.useCallback(()=>P("closed"),[P]),U=o.useRef(()=>{});o.useEffect(()=>{U.current=N},[N]),o.useEffect(()=>c==null?void 0:c.register(w,()=>U.current()),[c,w]),o.useEffect(()=>{I.current==="left"&&b.set(f.left),I.current==="right"&&b.set(-f.right)},[f,b]);let ee=o.useCallback(()=>{L.current=!1,J(!0),c==null||c.notifyOpen(w)},[c,w]),te=o.useCallback((s,u)=>{Math.abs(u.offset.x)>_e&&(L.current=!0);let p=r*m,T=b.get();p<=0||(T<=-p&&V.current.right?H("right"):T>=p&&V.current.left?H("left"):H(null))},[b,r,m,H]),ne=o.useCallback((s,u)=>{var _,re;J(!1);let p=M.current;if(p){H(null),L.current=!1,(re=(_=V.current)[p])==null||re.call(_),P("closed",u.velocity.x);return}let T=b.get()+u.velocity.x*n;f.right>0&&T<=-f.right*e?P("right",u.velocity.x):f.left>0&&T>=f.left*e?P("left",u.velocity.x):P("closed",u.velocity.x)},[b,n,f,e,P,H]),oe=o.useCallback(s=>{if(!(!L.current&&I.current==="closed")){if(s.preventDefault(),s.stopPropagation(),L.current){L.current=!1;return}N()}},[N]);o.useEffect(()=>{if(W==="closed")return;let s=T=>{var _;(_=x.current)!=null&&_.contains(T.target)||U.current()},u=T=>{T.key==="Escape"&&U.current()},p=()=>U.current();return document.addEventListener("pointerdown",s,!0),document.addEventListener("keydown",u),a&&window.addEventListener("scroll",p,!0),()=>{document.removeEventListener("pointerdown",s,!0),document.removeEventListener("keydown",u),a&&window.removeEventListener("scroll",p,!0)}},[W,a]);let he=o.useCallback(s=>{if(i||s.key!=="ArrowLeft"&&s.key!=="ArrowRight")return;let[u,p]=s.key==="ArrowLeft"?["left","right"]:["right","left"];if(I.current===u)P("closed");else if(f[p]>0)P(p);else return;s.preventDefault()},[i,f,P]),Ee=o.useMemo(()=>({state:W,disabled:i,dragging:j}),[W,i,j]),be=o.useMemo(()=>({state:W,disabled:i,dragging:j,x:b,leftWidth:f.left,rightWidth:f.right,itemWidth:m,armed:k,fullSwipeSides:Z,setStripWidth:Q,registerFullSwipe:X,close:N,onDragStart:ee,onDrag:te,onDragEnd:ne,onClickCapture:oe}),[W,i,j,b,f,m,k,Z,Q,X,N,ee,te,ne,oe]),Ce=K({defaultTagName:"div",render:t,state:Ee,props:D({"data-slot":"swipe-item",ref:x,style:Ne,onKeyDown:he},S)});return(0,z.jsx)(Se.Provider,{value:be,children:Ce})}function me(r){var i=r,{render:t,side:e}=i,n=A(i,["render","side"]);let{state:a,armed:l,x:S,leftWidth:R,rightWidth:y,fullSwipeSides:w,setStripWidth:c}=$(),v=o.useRef(null),x=w[e],f=e==="left"?R:y;o.useEffect(()=>{let m=v.current;if(!m)return;let h=new ResizeObserver(()=>{m.style.width||c(e,m.offsetWidth)});return h.observe(m),()=>{h.disconnect(),c(e,0)}},[e,c]),(0,E.useMotionValueEvent)(S,"change",m=>{let h=v.current;if(!h)return;let k=e==="left"?m:-m,G=k>0?"":"hidden";if(h.style.visibility!==G&&(h.style.visibility=G),!x)return;let M=k>f?`${Math.round(k)}px`:"";h.style.width!==M&&(h.style.width=M)});let d=K({defaultTagName:"div",render:t,props:D({"data-slot":"swipe-actions","data-side":e,"data-armed":l===e?"":void 0,ref:v,style:C(g({},Oe),{[e]:0}),inert:a!==e},n)});return(0,z.jsx)(Re.Provider,{value:e,children:d})}function ge(i){var a=i,{render:t,closeOnClick:e=!0,fullSwipe:n=!1}=a,r=A(a,["render","closeOnClick","fullSwipe"]);let{close:l,armed:S,registerFullSwipe:R}=$(),y=Fe(),w=(0,E.useReducedMotion)(),c=o.useRef(null),v=o.useRef(0);o.useEffect(()=>{if(n)return R(y,()=>{var d;(d=c.current)==null||d.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))})},[n,y,R]);let x=S===y,f=x&&!n;return o.useEffect(()=>{let d=c.current;if(!d||n)return;if(f){let h=d.offsetWidth;d.style.width||(v.current=h),d.style.boxSizing="border-box",d.style.overflow="clip",d.style.minWidth="0",d.style.paddingInline="0";let k=(0,E.animate)(d,{width:[h,0]},w?{duration:0}:ue);return()=>k.stop()}if(v.current===0)return;let m=(0,E.animate)(d,{width:[d.offsetWidth,v.current]},w?{duration:0}:ue);return m.then(()=>{d.style.width="",d.style.boxSizing="",d.style.overflow="",d.style.minWidth="",d.style.paddingInline=""}),()=>m.stop()},[f,n,w]),K({defaultTagName:"button",render:t,props:D({"data-slot":"swipe-action","data-armed":x&&n?"":void 0,ref:c,type:"button",style:n?{flexGrow:1}:void 0,onClick:()=>{e&&l()}},r)})}function ye(n){var r=n,{style:t}=r,e=A(r,["style"]);let v=$(),{x:i,disabled:a,dragging:l,leftWidth:S,rightWidth:R,itemWidth:y,fullSwipeSides:w}=v,c=A(v,["x","disabled","dragging","leftWidth","rightWidth","itemWidth","fullSwipeSides"]);return(0,z.jsx)(E.motion.div,C(g({"data-slot":"swipe-content"},e),{"data-dragging":l||void 0,style:C(g(g({},Ve),t),{x:i}),drag:a?!1:"x",dragConstraints:{left:-(w.right?y:R),right:w.left?y:S},dragElastic:.2,dragMomentum:!1,onDragStart:c.onDragStart,onDrag:c.onDrag,onDragEnd:c.onDragEnd,onClickCapture:c.onClickCapture}))}0&&(module.exports={SwipeAction,SwipeActions,SwipeContent,SwipeItem,SwipeRoot});
1
+ "use strict";"use client";var ke=Object.create;var B=Object.defineProperty,Ae=Object.defineProperties,Me=Object.getOwnPropertyDescriptor,De=Object.getOwnPropertyDescriptors,Ie=Object.getOwnPropertyNames,J=Object.getOwnPropertySymbols,We=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty,ce=Object.prototype.propertyIsEnumerable;var ae=(t,e,o)=>e in t?B(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o,C=(t,e)=>{for(var o in e||(e={}))Q.call(e,o)&&ae(t,o,e[o]);if(J)for(var o of J(e))ce.call(e,o)&&ae(t,o,e[o]);return t},b=(t,e)=>Ae(t,De(e));var W=(t,e)=>{var o={};for(var r in t)Q.call(t,r)&&e.indexOf(r)<0&&(o[r]=t[r]);if(t!=null&&J)for(var r of J(t))e.indexOf(r)<0&&ce.call(t,r)&&(o[r]=t[r]);return o};var Le=(t,e)=>{for(var o in e)B(t,o,{get:e[o],enumerable:!0})},le=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ie(e))!Q.call(t,s)&&s!==o&&B(t,s,{get:()=>e[s],enumerable:!(r=Me(e,s))||r.enumerable});return t};var ue=(t,e,o)=>(o=t!=null?ke(We(t)):{},le(e||!t||!t.__esModule?B(o,"default",{value:t,enumerable:!0}):o,t)),He=t=>le(B({},"__esModule",{value:!0}),t);var Be={};Le(Be,{SwipeAction:()=>Ce,SwipeActionContent:()=>ve,SwipeActions:()=>Ee,SwipeContent:()=>be,SwipeItem:()=>ye,SwipeRoot:()=>Se});module.exports=He(Be);var n=ue(require("react")),v=require("motion/react");var K=ue(require("react"));function j({defaultTagName:t,props:e,render:o,state:r={},stateAttributesMapping:s}){let i=L(Ne(r,s),e);if(!o)return K.createElement(t,i);if(typeof o=="function")return o(i,r);if(!K.isValidElement(o))return null;let c=o.props,u=L(i,c),w=b(C({},u),{ref:de(i.ref,c.ref)});return K.cloneElement(o,w)}function L(...t){let e={};for(let o of t){if(!o)continue;let r=o;for(let s of Object.keys(r)){let i=r[s];if(i===void 0)continue;let c=e[s];s==="className"?e[s]=[c,i].filter(Boolean).join(" "):s==="style"?e[s]=C(C({},c),i):s==="ref"?e[s]=de(c,i):Ve(s)&&typeof c=="function"&&typeof i=="function"?e[s]=Oe(i,c):e[s]=i}}return e}function Ne(t,e){var r;let o={};for(let s of Object.keys(t)){let i=t[s],c=(r=e==null?void 0:e[s])==null?void 0:r.call(e,i);if(c){Object.assign(o,c);continue}if(s==="slot"){o["data-slot"]=i;continue}let u=`data-${String(s).replace(/[A-Z]/g,w=>`-${w.toLowerCase()}`)}`;typeof i=="boolean"?o[u]=i?"":void 0:i!=null&&(o[u]=String(i))}return o}function Oe(t,e){return function(r){t(r),r.defaultPrevented||e(r)}}function Ve(t){return/^on[A-Z]/.test(t)}function de(...t){let e=t.filter(Boolean);if(e.length!==0)return o=>{for(let r of e)typeof r=="function"?r(o):r&&(r.current=o)}}var Y=require("react/jsx-runtime"),_e={position:"relative",isolation:"isolate",overflow:"clip"},Ue={position:"absolute",top:0,bottom:0,width:"100%",zIndex:0},Fe={position:"absolute",inset:0,display:"flex",pointerEvents:"none"},Ke={display:"flex",pointerEvents:"auto"},je={position:"relative",zIndex:1},pe={type:"spring",stiffness:500,damping:45,mass:.8},Ye=b(C({},pe),{damping:36}),ze=4,Ge={duration:.18,ease:[.32,.72,0,1]},fe=n.createContext(null);function Se(o){var r=o,{render:t}=r,e=W(r,["render"]);let s=n.useRef(new Map),i=n.useMemo(()=>({register(u,w){return s.current.set(u,w),()=>{s.current.delete(u)}},notifyOpen(u){for(let[w,y]of s.current)w!==u&&y()}}),[]),c=j({defaultTagName:"div",render:t,props:L({"data-slot":"swipe-root"},e)});return(0,Y.jsx)(fe.Provider,{value:i,children:c})}var Re=n.createContext(null),we=n.createContext(null),me=n.createContext(null);function $e(){let t=n.useContext(me);if(!t)throw new Error("SwipeActionContent must be used within SwipeAction");return t}function ge(){let t=n.useContext(we);if(!t)throw new Error("SwipeAction must be used within SwipeActions");return t}function X(){let t=n.useContext(Re);if(!t)throw new Error("Swipe parts must be used within SwipeItem");return t}function ye(w){var y=w,{render:t,threshold:e=.5,velocityFactor:o=.2,fullSwipeThreshold:r=.5,disabled:s=!1,closeOnScroll:i=!1,onOpenChange:c}=y,u=W(y,["render","threshold","velocityFactor","fullSwipeThreshold","disabled","closeOnScroll","onOpenChange"]);let E=n.useId(),l=n.useContext(fe),m=(0,v.useReducedMotion)(),D=n.useRef(null),[S,H]=n.useState({left:0,right:0}),[h,I]=n.useState(0),[T,N]=n.useState(null),p=n.useRef(null),R=n.useRef({}),[g,A]=n.useState({left:!1,right:!1}),[x,z]=n.useState("closed"),[O,Z]=n.useState(!1),V=n.useRef("closed"),_=n.useRef(!1),P=(0,v.useMotionValue)(0),q=(0,v.useMotionValue)(1),ee=n.useCallback((a,d)=>{H(f=>f[a]===d?f:b(C({},f),{[a]:d}))},[]),te=n.useCallback((a,d)=>(R.current[a]=d,A(f=>b(C({},f),{[a]:!0})),()=>{delete R.current[a],A(f=>b(C({},f),{[a]:!1}))}),[]),U=n.useCallback(a=>{p.current!==a&&(p.current=a,N(a))},[]);n.useEffect(()=>{(0,v.animate)(q,T?0:1,m?{duration:0}:Ge)},[T,q,m]),n.useEffect(()=>{let a=D.current;if(!a)return;let d=new ResizeObserver(()=>I(a.offsetWidth));return d.observe(a),()=>d.disconnect()},[]);let k=n.useCallback((a,d)=>{let f=a==="left"?S.left:a==="right"?-S.right:0;(0,v.animate)(P,f,m?{duration:0}:d===void 0?pe:b(C({},Ye),{velocity:d})),a!=="closed"&&(l==null||l.notifyOpen(E)),V.current!==a&&(V.current=a,z(a),c==null||c(a))},[S,P,m,l,E,c]),F=n.useCallback(()=>k("closed"),[k]),G=n.useRef(()=>{});n.useEffect(()=>{G.current=F},[F]),n.useEffect(()=>l==null?void 0:l.register(E,()=>G.current()),[l,E]),n.useEffect(()=>{V.current==="left"&&P.set(S.left),V.current==="right"&&P.set(-S.right)},[S,P]);let ne=n.useCallback(()=>{_.current=!1,Z(!0),l==null||l.notifyOpen(E)},[l,E]),oe=n.useCallback((a,d)=>{Math.abs(d.offset.x)>ze&&(_.current=!0);let f=r*h,M=P.get();f<=0||(M<=-f&&R.current.right?U("right"):M>=f&&R.current.left?U("left"):U(null))},[P,r,h,U]),re=n.useCallback((a,d)=>{var $,ie;Z(!1);let f=p.current;if(f){U(null),_.current=!1,(ie=($=R.current)[f])==null||ie.call($),k("closed",d.velocity.x);return}let M=P.get()+d.velocity.x*o;S.right>0&&M<=-S.right*e?k("right",d.velocity.x):S.left>0&&M>=S.left*e?k("left",d.velocity.x):k("closed",d.velocity.x)},[P,o,S,e,k,U]),se=n.useCallback(a=>{if(!(!_.current&&V.current==="closed")){if(a.preventDefault(),a.stopPropagation(),_.current){_.current=!1;return}F()}},[F]);n.useEffect(()=>{if(x==="closed")return;let a=M=>{var $;($=D.current)!=null&&$.contains(M.target)||G.current()},d=M=>{M.key==="Escape"&&G.current()},f=()=>G.current();return document.addEventListener("pointerdown",a,!0),document.addEventListener("keydown",d),i&&window.addEventListener("scroll",f,!0),()=>{document.removeEventListener("pointerdown",a,!0),document.removeEventListener("keydown",d),i&&window.removeEventListener("scroll",f,!0)}},[x,i]);let he=n.useCallback(a=>{if(s||a.key!=="ArrowLeft"&&a.key!=="ArrowRight")return;let[d,f]=a.key==="ArrowLeft"?["left","right"]:["right","left"];if(V.current===d)k("closed");else if(S[f]>0)k(f);else return;a.preventDefault()},[s,S,k]),xe=n.useMemo(()=>({state:x,disabled:s,dragging:O}),[x,s,O]),Pe=n.useMemo(()=>({state:x,disabled:s,dragging:O,x:P,collapse:q,leftWidth:S.left,rightWidth:S.right,itemWidth:h,armed:T,fullSwipeSides:g,setStripWidth:ee,registerFullSwipe:te,close:F,onDragStart:ne,onDrag:oe,onDragEnd:re,onClickCapture:se}),[x,s,O,P,q,S,h,T,g,ee,te,F,ne,oe,re,se]),Te=j({defaultTagName:"div",render:t,state:xe,props:L({"data-slot":"swipe-item",ref:D,style:_e,onKeyDown:he},u)});return(0,Y.jsx)(Re.Provider,{value:Pe,children:Te})}function Ee(s){var i=s,{render:t,side:e,fullSwipe:o=!1}=i,r=W(i,["render","side","fullSwipe"]);let{state:c,armed:u,x:w,setStripWidth:y}=X(),E=n.useRef(null),[l,m]=n.useState([]),D=n.useCallback((p,R)=>{m(g=>{let A=g.findIndex(z=>z.id===p);if(A===-1)return[...g,{id:p,width:R}];if(g[A].width===R)return g;let x=[...g];return x[A]={id:p,width:R},x})},[]),S=n.useCallback(p=>{m(R=>R.filter(g=>g.id!==p))},[]),H=n.useCallback(p=>{let R=0;for(let g of l){if(g.id===p)break;R+=g.width}return R},[l]),h=l.reduce((p,R)=>p+R.width,0);n.useEffect(()=>(y(e,h),()=>y(e,0)),[e,h,y]),(0,v.useMotionValueEvent)(w,"change",p=>{let R=E.current;R&&(R.style.transform=`translate3d(${Math.round(p)}px, 0, 0)`)});let I=n.useCallback(p=>l.length>0&&l[l.length-1].id===p,[l]),T=n.useMemo(()=>({side:e,fullSwipe:o,measure:D,forget:S,offsetOf:H,isOutermost:I}),[e,o,D,S,H,I]),N=j({defaultTagName:"div",render:t,props:L({"data-slot":"swipe-actions","data-side":e,"data-armed":u===e?"":void 0,ref:E,style:b(C({},Ue),{[e==="left"?"right":"left"]:"100%"}),inert:c!==e},r)});return(0,Y.jsx)(we.Provider,{value:T,children:N})}function Ce(r){var s=r,{render:t,closeOnClick:e=!0}=s,o=W(s,["render","closeOnClick"]);let{close:i,armed:c,x:u,collapse:w,leftWidth:y,rightWidth:E,registerFullSwipe:l}=X(),{side:m,fullSwipe:D,offsetOf:S,isOutermost:H}=ge(),h=n.useId(),I=n.useRef(null),T=D&&H(h);n.useEffect(()=>{if(T)return l(m,()=>{var g;(g=I.current)==null||g.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))})},[T,m,l]);let N=S(h),p=n.useCallback(()=>{let g=I.current;if(!g)return;let A=m==="left"?y:E,x=Math.max(0,m==="left"?u.get():-u.get()),z=w.get(),O=A>0?Math.min(1,x/A):0,Z=N*O*z*(m==="left"?-1:1);g.style.transform=`translate3d(${Z.toFixed(2)}px, 0, 0)`},[N,m,y,E,u,w]);(0,v.useMotionValueEvent)(u,"change",p),(0,v.useMotionValueEvent)(w,"change",p),n.useEffect(p,[p]);let R=j({defaultTagName:"button",render:t,props:L({"data-slot":"swipe-action","data-armed":c===m&&T?"":void 0,ref:I,type:"button",style:b(C({},Fe),{justifyContent:m==="left"?"flex-end":"flex-start"}),onClick:()=>{e&&i()}},o)});return(0,Y.jsx)(me.Provider,{value:h,children:R})}function ve(o){var r=o,{render:t}=r,e=W(r,["render"]);let{measure:s,forget:i}=ge(),c=$e(),u=n.useRef(null);return n.useEffect(()=>{let w=u.current;if(!w)return;let y=new ResizeObserver(()=>s(c,w.offsetWidth));return y.observe(w),()=>{y.disconnect(),i(c)}},[c,s,i]),j({defaultTagName:"span",render:t,props:L({"data-slot":"swipe-action-content",ref:u,style:Ke},e)})}function be(o){var r=o,{style:t}=r,e=W(r,["style"]);let m=X(),{x:s,disabled:i,dragging:c,leftWidth:u,rightWidth:w,itemWidth:y,fullSwipeSides:E}=m,l=W(m,["x","disabled","dragging","leftWidth","rightWidth","itemWidth","fullSwipeSides"]);return(0,Y.jsx)(v.motion.div,b(C({"data-slot":"swipe-content"},e),{"data-dragging":c||void 0,style:b(C(C({},je),t),{x:s}),drag:i?!1:"x",dragConstraints:{left:-(E.right?y:w),right:E.left?y:u},dragElastic:.2,dragMomentum:!1,onDragStart:l.onDragStart,onDrag:l.onDrag,onDragEnd:l.onDragEnd,onClickCapture:l.onClickCapture}))}0&&(module.exports={SwipeAction,SwipeActionContent,SwipeActions,SwipeContent,SwipeItem,SwipeRoot});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- "use client";var ge=Object.defineProperty,ye=Object.defineProperties;var ve=Object.getOwnPropertyDescriptors;var z=Object.getOwnPropertySymbols;var re=Object.prototype.hasOwnProperty,ie=Object.prototype.propertyIsEnumerable;var oe=(o,e,n)=>e in o?ge(o,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):o[e]=n,g=(o,e)=>{for(var n in e||(e={}))re.call(e,n)&&oe(o,n,e[n]);if(z)for(var n of z(e))ie.call(e,n)&&oe(o,n,e[n]);return o},b=(o,e)=>ye(o,ve(e));var k=(o,e)=>{var n={};for(var r in o)re.call(o,r)&&e.indexOf(r)<0&&(n[r]=o[r]);if(o!=null&&z)for(var r of z(o))e.indexOf(r)<0&&ie.call(o,r)&&(n[r]=o[r]);return n};import*as t from"react";import{animate as j,motion as Ce,useMotionValue as Pe,useMotionValueEvent as Te,useReducedMotion as ce}from"motion/react";import*as N from"react";function _({defaultTagName:o,props:e,render:n,state:r={},stateAttributesMapping:s}){let a=A(he(r,s),e);if(!n)return N.createElement(o,a);if(typeof n=="function")return n(a,r);if(!N.isValidElement(n))return null;let l=n.props,S=A(a,l),R=b(g({},S),{ref:se(a.ref,l.ref)});return N.cloneElement(n,R)}function A(...o){let e={};for(let n of o){if(!n)continue;let r=n;for(let s of Object.keys(r)){let a=r[s];if(a===void 0)continue;let l=e[s];s==="className"?e[s]=[l,a].filter(Boolean).join(" "):s==="style"?e[s]=g(g({},l),a):s==="ref"?e[s]=se(l,a):be(s)&&typeof l=="function"&&typeof a=="function"?e[s]=Ee(a,l):e[s]=a}}return e}function he(o,e){var r;let n={};for(let s of Object.keys(o)){let a=o[s],l=(r=e==null?void 0:e[s])==null?void 0:r.call(e,a);if(l){Object.assign(n,l);continue}if(s==="slot"){n["data-slot"]=a;continue}let S=`data-${String(s).replace(/[A-Z]/g,R=>`-${R.toLowerCase()}`)}`;typeof a=="boolean"?n[S]=a?"":void 0:a!=null&&(n[S]=String(a))}return n}function Ee(o,e){return function(r){o(r),r.defaultPrevented||e(r)}}function be(o){return/^on[A-Z]/.test(o)}function se(...o){let e=o.filter(Boolean);if(e.length!==0)return n=>{for(let r of e)typeof r=="function"?r(n):r&&(r.current=n)}}import{jsx as G}from"react/jsx-runtime";var xe={position:"relative",isolation:"isolate",overflow:"clip"},ke={position:"absolute",top:0,bottom:0,zIndex:0,display:"flex"},Ae={position:"relative",zIndex:1},le={type:"spring",stiffness:500,damping:45,mass:.8},De=b(g({},le),{damping:36}),Me=4,ae={duration:.18,ease:[.32,.72,0,1]},ue=t.createContext(null);function We(n){var r=n,{render:o}=r,e=k(r,["render"]);let s=t.useRef(new Map),a=t.useMemo(()=>({register(S,R){return s.current.set(S,R),()=>{s.current.delete(S)}},notifyOpen(S){for(let[R,y]of s.current)R!==S&&y()}}),[]),l=_({defaultTagName:"div",render:o,props:A({"data-slot":"swipe-root"},e)});return G(ue.Provider,{value:a,children:l})}var de=t.createContext(null),pe=t.createContext(null);function Ie(){let o=t.useContext(pe);if(!o)throw new Error("SwipeAction must be used within SwipeActions");return o}function B(){let o=t.useContext(de);if(!o)throw new Error("Swipe parts must be used within SwipeItem");return o}function Le(R){var y=R,{render:o,threshold:e=.5,velocityFactor:n=.2,fullSwipeThreshold:r=.5,disabled:s=!1,closeOnScroll:a=!1,onOpenChange:l}=y,S=k(y,["render","threshold","velocityFactor","fullSwipeThreshold","disabled","closeOnScroll","onOpenChange"]);let w=t.useId(),c=t.useContext(ue),v=ce(),T=t.useRef(null),[f,d]=t.useState({left:0,right:0}),[m,h]=t.useState(0),[x,F]=t.useState(null),D=t.useRef(null),O=t.useRef({}),[Y,$]=t.useState({left:!1,right:!1}),[M,fe]=t.useState("closed"),[K,Z]=t.useState(!1),W=t.useRef("closed"),I=t.useRef(!1),E=Pe(0),q=t.useCallback((i,u)=>{d(p=>p[i]===u?p:b(g({},p),{[i]:u}))},[]),J=t.useCallback((i,u)=>(O.current[i]=u,$(p=>b(g({},p),{[i]:!0})),()=>{delete O.current[i],$(p=>b(g({},p),{[i]:!1}))}),[]),L=t.useCallback(i=>{D.current!==i&&(D.current=i,F(i))},[]);t.useEffect(()=>{let i=T.current;if(!i)return;let u=new ResizeObserver(()=>h(i.offsetWidth));return u.observe(i),()=>u.disconnect()},[]);let C=t.useCallback((i,u)=>{let p=i==="left"?f.left:i==="right"?-f.right:0;j(E,p,v?{duration:0}:u===void 0?le:b(g({},De),{velocity:u})),i!=="closed"&&(c==null||c.notifyOpen(w)),W.current!==i&&(W.current=i,fe(i),l==null||l(i))},[f,E,v,c,w,l]),H=t.useCallback(()=>C("closed"),[C]),V=t.useRef(()=>{});t.useEffect(()=>{V.current=H},[H]),t.useEffect(()=>c==null?void 0:c.register(w,()=>V.current()),[c,w]),t.useEffect(()=>{W.current==="left"&&E.set(f.left),W.current==="right"&&E.set(-f.right)},[f,E]);let Q=t.useCallback(()=>{I.current=!1,Z(!0),c==null||c.notifyOpen(w)},[c,w]),X=t.useCallback((i,u)=>{Math.abs(u.offset.x)>Me&&(I.current=!0);let p=r*m,P=E.get();p<=0||(P<=-p&&O.current.right?L("right"):P>=p&&O.current.left?L("left"):L(null))},[E,r,m,L]),ee=t.useCallback((i,u)=>{var U,ne;Z(!1);let p=D.current;if(p){L(null),I.current=!1,(ne=(U=O.current)[p])==null||ne.call(U),C("closed",u.velocity.x);return}let P=E.get()+u.velocity.x*n;f.right>0&&P<=-f.right*e?C("right",u.velocity.x):f.left>0&&P>=f.left*e?C("left",u.velocity.x):C("closed",u.velocity.x)},[E,n,f,e,C,L]),te=t.useCallback(i=>{if(!(!I.current&&W.current==="closed")){if(i.preventDefault(),i.stopPropagation(),I.current){I.current=!1;return}H()}},[H]);t.useEffect(()=>{if(M==="closed")return;let i=P=>{var U;(U=T.current)!=null&&U.contains(P.target)||V.current()},u=P=>{P.key==="Escape"&&V.current()},p=()=>V.current();return document.addEventListener("pointerdown",i,!0),document.addEventListener("keydown",u),a&&window.addEventListener("scroll",p,!0),()=>{document.removeEventListener("pointerdown",i,!0),document.removeEventListener("keydown",u),a&&window.removeEventListener("scroll",p,!0)}},[M,a]);let Se=t.useCallback(i=>{if(s||i.key!=="ArrowLeft"&&i.key!=="ArrowRight")return;let[u,p]=i.key==="ArrowLeft"?["left","right"]:["right","left"];if(W.current===u)C("closed");else if(f[p]>0)C(p);else return;i.preventDefault()},[s,f,C]),Re=t.useMemo(()=>({state:M,disabled:s,dragging:K}),[M,s,K]),we=t.useMemo(()=>({state:M,disabled:s,dragging:K,x:E,leftWidth:f.left,rightWidth:f.right,itemWidth:m,armed:x,fullSwipeSides:Y,setStripWidth:q,registerFullSwipe:J,close:H,onDragStart:Q,onDrag:X,onDragEnd:ee,onClickCapture:te}),[M,s,K,E,f,m,x,Y,q,J,H,Q,X,ee,te]),me=_({defaultTagName:"div",render:o,state:Re,props:A({"data-slot":"swipe-item",ref:T,style:xe,onKeyDown:Se},S)});return G(de.Provider,{value:we,children:me})}function He(r){var s=r,{render:o,side:e}=s,n=k(s,["render","side"]);let{state:a,armed:l,x:S,leftWidth:R,rightWidth:y,fullSwipeSides:w,setStripWidth:c}=B(),v=t.useRef(null),T=w[e],f=e==="left"?R:y;t.useEffect(()=>{let m=v.current;if(!m)return;let h=new ResizeObserver(()=>{m.style.width||c(e,m.offsetWidth)});return h.observe(m),()=>{h.disconnect(),c(e,0)}},[e,c]),Te(S,"change",m=>{let h=v.current;if(!h)return;let x=e==="left"?m:-m,F=x>0?"":"hidden";if(h.style.visibility!==F&&(h.style.visibility=F),!T)return;let D=x>f?`${Math.round(x)}px`:"";h.style.width!==D&&(h.style.width=D)});let d=_({defaultTagName:"div",render:o,props:A({"data-slot":"swipe-actions","data-side":e,"data-armed":l===e?"":void 0,ref:v,style:b(g({},ke),{[e]:0}),inert:a!==e},n)});return G(pe.Provider,{value:e,children:d})}function Ne(s){var a=s,{render:o,closeOnClick:e=!0,fullSwipe:n=!1}=a,r=k(a,["render","closeOnClick","fullSwipe"]);let{close:l,armed:S,registerFullSwipe:R}=B(),y=Ie(),w=ce(),c=t.useRef(null),v=t.useRef(0);t.useEffect(()=>{if(n)return R(y,()=>{var d;(d=c.current)==null||d.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))})},[n,y,R]);let T=S===y,f=T&&!n;return t.useEffect(()=>{let d=c.current;if(!d||n)return;if(f){let h=d.offsetWidth;d.style.width||(v.current=h),d.style.boxSizing="border-box",d.style.overflow="clip",d.style.minWidth="0",d.style.paddingInline="0";let x=j(d,{width:[h,0]},w?{duration:0}:ae);return()=>x.stop()}if(v.current===0)return;let m=j(d,{width:[d.offsetWidth,v.current]},w?{duration:0}:ae);return m.then(()=>{d.style.width="",d.style.boxSizing="",d.style.overflow="",d.style.minWidth="",d.style.paddingInline=""}),()=>m.stop()},[f,n,w]),_({defaultTagName:"button",render:o,props:A({"data-slot":"swipe-action","data-armed":T&&n?"":void 0,ref:c,type:"button",style:n?{flexGrow:1}:void 0,onClick:()=>{e&&l()}},r)})}function Oe(n){var r=n,{style:o}=r,e=k(r,["style"]);let v=B(),{x:s,disabled:a,dragging:l,leftWidth:S,rightWidth:R,itemWidth:y,fullSwipeSides:w}=v,c=k(v,["x","disabled","dragging","leftWidth","rightWidth","itemWidth","fullSwipeSides"]);return G(Ce.div,b(g({"data-slot":"swipe-content"},e),{"data-dragging":l||void 0,style:b(g(g({},Ae),o),{x:s}),drag:a?!1:"x",dragConstraints:{left:-(w.right?y:R),right:w.left?y:S},dragElastic:.2,dragMomentum:!1,onDragStart:c.onDragStart,onDrag:c.onDrag,onDragEnd:c.onDragEnd,onClickCapture:c.onClickCapture}))}export{Ne as SwipeAction,He as SwipeActions,Oe as SwipeContent,Le as SwipeItem,We as SwipeRoot};
1
+ "use client";var Ce=Object.defineProperty,ve=Object.defineProperties;var be=Object.getOwnPropertyDescriptors;var Z=Object.getOwnPropertySymbols;var ie=Object.prototype.hasOwnProperty,ae=Object.prototype.propertyIsEnumerable;var se=(n,t,o)=>t in n?Ce(n,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):n[t]=o,C=(n,t)=>{for(var o in t||(t={}))ie.call(t,o)&&se(n,o,t[o]);if(Z)for(var o of Z(t))ae.call(t,o)&&se(n,o,t[o]);return n},v=(n,t)=>ve(n,be(t));var I=(n,t)=>{var o={};for(var r in n)ie.call(n,r)&&t.indexOf(r)<0&&(o[r]=n[r]);if(n!=null&&Z)for(var r of Z(n))t.indexOf(r)<0&&ae.call(n,r)&&(o[r]=n[r]);return o};import*as e from"react";import{animate as le,motion as Te,useMotionValue as ue,useMotionValueEvent as q,useReducedMotion as ke}from"motion/react";import*as F from"react";function K({defaultTagName:n,props:t,render:o,state:r={},stateAttributesMapping:s}){let i=W(he(r,s),t);if(!o)return F.createElement(n,i);if(typeof o=="function")return o(i,r);if(!F.isValidElement(o))return null;let c=o.props,u=W(i,c),w=v(C({},u),{ref:ce(i.ref,c.ref)});return F.cloneElement(o,w)}function W(...n){let t={};for(let o of n){if(!o)continue;let r=o;for(let s of Object.keys(r)){let i=r[s];if(i===void 0)continue;let c=t[s];s==="className"?t[s]=[c,i].filter(Boolean).join(" "):s==="style"?t[s]=C(C({},c),i):s==="ref"?t[s]=ce(c,i):Pe(s)&&typeof c=="function"&&typeof i=="function"?t[s]=xe(i,c):t[s]=i}}return t}function he(n,t){var r;let o={};for(let s of Object.keys(n)){let i=n[s],c=(r=t==null?void 0:t[s])==null?void 0:r.call(t,i);if(c){Object.assign(o,c);continue}if(s==="slot"){o["data-slot"]=i;continue}let u=`data-${String(s).replace(/[A-Z]/g,w=>`-${w.toLowerCase()}`)}`;typeof i=="boolean"?o[u]=i?"":void 0:i!=null&&(o[u]=String(i))}return o}function xe(n,t){return function(r){n(r),r.defaultPrevented||t(r)}}function Pe(n){return/^on[A-Z]/.test(n)}function ce(...n){let t=n.filter(Boolean);if(t.length!==0)return o=>{for(let r of t)typeof r=="function"?r(o):r&&(r.current=o)}}import{jsx as G}from"react/jsx-runtime";var Ae={position:"relative",isolation:"isolate",overflow:"clip"},Me={position:"absolute",top:0,bottom:0,width:"100%",zIndex:0},De={position:"absolute",inset:0,display:"flex",pointerEvents:"none"},Ie={display:"flex",pointerEvents:"auto"},We={position:"relative",zIndex:1},de={type:"spring",stiffness:500,damping:45,mass:.8},Le=v(C({},de),{damping:36}),He=4,Ne={duration:.18,ease:[.32,.72,0,1]},pe=e.createContext(null);function Oe(o){var r=o,{render:n}=r,t=I(r,["render"]);let s=e.useRef(new Map),i=e.useMemo(()=>({register(u,w){return s.current.set(u,w),()=>{s.current.delete(u)}},notifyOpen(u){for(let[w,y]of s.current)w!==u&&y()}}),[]),c=K({defaultTagName:"div",render:n,props:W({"data-slot":"swipe-root"},t)});return G(pe.Provider,{value:i,children:c})}var fe=e.createContext(null),Se=e.createContext(null),Re=e.createContext(null);function Ve(){let n=e.useContext(Re);if(!n)throw new Error("SwipeActionContent must be used within SwipeAction");return n}function we(){let n=e.useContext(Se);if(!n)throw new Error("SwipeAction must be used within SwipeActions");return n}function J(){let n=e.useContext(fe);if(!n)throw new Error("Swipe parts must be used within SwipeItem");return n}function _e(w){var y=w,{render:n,threshold:t=.5,velocityFactor:o=.2,fullSwipeThreshold:r=.5,disabled:s=!1,closeOnScroll:i=!1,onOpenChange:c}=y,u=I(y,["render","threshold","velocityFactor","fullSwipeThreshold","disabled","closeOnScroll","onOpenChange"]);let E=e.useId(),l=e.useContext(pe),m=ke(),M=e.useRef(null),[S,L]=e.useState({left:0,right:0}),[b,D]=e.useState(0),[P,H]=e.useState(null),p=e.useRef(null),R=e.useRef({}),[g,k]=e.useState({left:!1,right:!1}),[h,j]=e.useState("closed"),[N,$]=e.useState(!1),O=e.useRef("closed"),V=e.useRef(!1),x=ue(0),B=ue(1),Q=e.useCallback((a,d)=>{L(f=>f[a]===d?f:v(C({},f),{[a]:d}))},[]),X=e.useCallback((a,d)=>(R.current[a]=d,k(f=>v(C({},f),{[a]:!0})),()=>{delete R.current[a],k(f=>v(C({},f),{[a]:!1}))}),[]),_=e.useCallback(a=>{p.current!==a&&(p.current=a,H(a))},[]);e.useEffect(()=>{le(B,P?0:1,m?{duration:0}:Ne)},[P,B,m]),e.useEffect(()=>{let a=M.current;if(!a)return;let d=new ResizeObserver(()=>D(a.offsetWidth));return d.observe(a),()=>d.disconnect()},[]);let T=e.useCallback((a,d)=>{let f=a==="left"?S.left:a==="right"?-S.right:0;le(x,f,m?{duration:0}:d===void 0?de:v(C({},Le),{velocity:d})),a!=="closed"&&(l==null||l.notifyOpen(E)),O.current!==a&&(O.current=a,j(a),c==null||c(a))},[S,x,m,l,E,c]),U=e.useCallback(()=>T("closed"),[T]),Y=e.useRef(()=>{});e.useEffect(()=>{Y.current=U},[U]),e.useEffect(()=>l==null?void 0:l.register(E,()=>Y.current()),[l,E]),e.useEffect(()=>{O.current==="left"&&x.set(S.left),O.current==="right"&&x.set(-S.right)},[S,x]);let ee=e.useCallback(()=>{V.current=!1,$(!0),l==null||l.notifyOpen(E)},[l,E]),te=e.useCallback((a,d)=>{Math.abs(d.offset.x)>He&&(V.current=!0);let f=r*b,A=x.get();f<=0||(A<=-f&&R.current.right?_("right"):A>=f&&R.current.left?_("left"):_(null))},[x,r,b,_]),ne=e.useCallback((a,d)=>{var z,re;$(!1);let f=p.current;if(f){_(null),V.current=!1,(re=(z=R.current)[f])==null||re.call(z),T("closed",d.velocity.x);return}let A=x.get()+d.velocity.x*o;S.right>0&&A<=-S.right*t?T("right",d.velocity.x):S.left>0&&A>=S.left*t?T("left",d.velocity.x):T("closed",d.velocity.x)},[x,o,S,t,T,_]),oe=e.useCallback(a=>{if(!(!V.current&&O.current==="closed")){if(a.preventDefault(),a.stopPropagation(),V.current){V.current=!1;return}U()}},[U]);e.useEffect(()=>{if(h==="closed")return;let a=A=>{var z;(z=M.current)!=null&&z.contains(A.target)||Y.current()},d=A=>{A.key==="Escape"&&Y.current()},f=()=>Y.current();return document.addEventListener("pointerdown",a,!0),document.addEventListener("keydown",d),i&&window.addEventListener("scroll",f,!0),()=>{document.removeEventListener("pointerdown",a,!0),document.removeEventListener("keydown",d),i&&window.removeEventListener("scroll",f,!0)}},[h,i]);let me=e.useCallback(a=>{if(s||a.key!=="ArrowLeft"&&a.key!=="ArrowRight")return;let[d,f]=a.key==="ArrowLeft"?["left","right"]:["right","left"];if(O.current===d)T("closed");else if(S[f]>0)T(f);else return;a.preventDefault()},[s,S,T]),ge=e.useMemo(()=>({state:h,disabled:s,dragging:N}),[h,s,N]),ye=e.useMemo(()=>({state:h,disabled:s,dragging:N,x,collapse:B,leftWidth:S.left,rightWidth:S.right,itemWidth:b,armed:P,fullSwipeSides:g,setStripWidth:Q,registerFullSwipe:X,close:U,onDragStart:ee,onDrag:te,onDragEnd:ne,onClickCapture:oe}),[h,s,N,x,B,S,b,P,g,Q,X,U,ee,te,ne,oe]),Ee=K({defaultTagName:"div",render:n,state:ge,props:W({"data-slot":"swipe-item",ref:M,style:Ae,onKeyDown:me},u)});return G(fe.Provider,{value:ye,children:Ee})}function Ue(s){var i=s,{render:n,side:t,fullSwipe:o=!1}=i,r=I(i,["render","side","fullSwipe"]);let{state:c,armed:u,x:w,setStripWidth:y}=J(),E=e.useRef(null),[l,m]=e.useState([]),M=e.useCallback((p,R)=>{m(g=>{let k=g.findIndex(j=>j.id===p);if(k===-1)return[...g,{id:p,width:R}];if(g[k].width===R)return g;let h=[...g];return h[k]={id:p,width:R},h})},[]),S=e.useCallback(p=>{m(R=>R.filter(g=>g.id!==p))},[]),L=e.useCallback(p=>{let R=0;for(let g of l){if(g.id===p)break;R+=g.width}return R},[l]),b=l.reduce((p,R)=>p+R.width,0);e.useEffect(()=>(y(t,b),()=>y(t,0)),[t,b,y]),q(w,"change",p=>{let R=E.current;R&&(R.style.transform=`translate3d(${Math.round(p)}px, 0, 0)`)});let D=e.useCallback(p=>l.length>0&&l[l.length-1].id===p,[l]),P=e.useMemo(()=>({side:t,fullSwipe:o,measure:M,forget:S,offsetOf:L,isOutermost:D}),[t,o,M,S,L,D]),H=K({defaultTagName:"div",render:n,props:W({"data-slot":"swipe-actions","data-side":t,"data-armed":u===t?"":void 0,ref:E,style:v(C({},Me),{[t==="left"?"right":"left"]:"100%"}),inert:c!==t},r)});return G(Se.Provider,{value:P,children:H})}function Fe(r){var s=r,{render:n,closeOnClick:t=!0}=s,o=I(s,["render","closeOnClick"]);let{close:i,armed:c,x:u,collapse:w,leftWidth:y,rightWidth:E,registerFullSwipe:l}=J(),{side:m,fullSwipe:M,offsetOf:S,isOutermost:L}=we(),b=e.useId(),D=e.useRef(null),P=M&&L(b);e.useEffect(()=>{if(P)return l(m,()=>{var g;(g=D.current)==null||g.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))})},[P,m,l]);let H=S(b),p=e.useCallback(()=>{let g=D.current;if(!g)return;let k=m==="left"?y:E,h=Math.max(0,m==="left"?u.get():-u.get()),j=w.get(),N=k>0?Math.min(1,h/k):0,$=H*N*j*(m==="left"?-1:1);g.style.transform=`translate3d(${$.toFixed(2)}px, 0, 0)`},[H,m,y,E,u,w]);q(u,"change",p),q(w,"change",p),e.useEffect(p,[p]);let R=K({defaultTagName:"button",render:n,props:W({"data-slot":"swipe-action","data-armed":c===m&&P?"":void 0,ref:D,type:"button",style:v(C({},De),{justifyContent:m==="left"?"flex-end":"flex-start"}),onClick:()=>{t&&i()}},o)});return G(Re.Provider,{value:b,children:R})}function Ke(o){var r=o,{render:n}=r,t=I(r,["render"]);let{measure:s,forget:i}=we(),c=Ve(),u=e.useRef(null);return e.useEffect(()=>{let w=u.current;if(!w)return;let y=new ResizeObserver(()=>s(c,w.offsetWidth));return y.observe(w),()=>{y.disconnect(),i(c)}},[c,s,i]),K({defaultTagName:"span",render:n,props:W({"data-slot":"swipe-action-content",ref:u,style:Ie},t)})}function je(o){var r=o,{style:n}=r,t=I(r,["style"]);let m=J(),{x:s,disabled:i,dragging:c,leftWidth:u,rightWidth:w,itemWidth:y,fullSwipeSides:E}=m,l=I(m,["x","disabled","dragging","leftWidth","rightWidth","itemWidth","fullSwipeSides"]);return G(Te.div,v(C({"data-slot":"swipe-content"},t),{"data-dragging":c||void 0,style:v(C(C({},We),n),{x:s}),drag:i?!1:"x",dragConstraints:{left:-(E.right?y:w),right:E.left?y:u},dragElastic:.2,dragMomentum:!1,onDragStart:l.onDragStart,onDrag:l.onDrag,onDragEnd:l.onDragEnd,onClickCapture:l.onClickCapture}))}export{Fe as SwipeAction,Ke as SwipeActionContent,Ue as SwipeActions,je as SwipeContent,_e as SwipeItem,Oe as SwipeRoot};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncdai/react-swipe-actions",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Unstyled swipe actions for React. Swipe a row in a list to reveal actions on the left or right.",
5
5
  "publishConfig": {
6
6
  "access": "public",