react-swipe-action 0.0.3 → 0.1.1
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/dist/SwipeAction.d.ts +3 -10
- package/dist/SwipeAction.js.map +1 -1
- package/package.json +1 -1
package/dist/SwipeAction.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { FunctionComponent, ReactNode
|
|
1
|
+
import type { FunctionComponent, ReactNode } from 'react';
|
|
2
2
|
type OnLongSwipe = () => void;
|
|
3
3
|
type Content = ReactNode;
|
|
4
|
-
type Action = {
|
|
4
|
+
export type Action = {
|
|
5
5
|
background?: ReactNode;
|
|
6
6
|
content?: Content;
|
|
7
7
|
onLongSwipe?: OnLongSwipe;
|
|
@@ -10,17 +10,10 @@ type Action = {
|
|
|
10
10
|
} | {
|
|
11
11
|
onLongSwipe: OnLongSwipe;
|
|
12
12
|
});
|
|
13
|
-
type SwipeActionProps = {
|
|
13
|
+
export type SwipeActionProps = {
|
|
14
14
|
main: (handle: ReactNode) => ReactNode;
|
|
15
15
|
startAction?: Action;
|
|
16
16
|
endAction?: Action;
|
|
17
17
|
};
|
|
18
18
|
export declare const SwipeAction: FunctionComponent<SwipeActionProps>;
|
|
19
|
-
type Position = 'start' | 'end';
|
|
20
|
-
declare const Action: FunctionComponent<{
|
|
21
|
-
position: Position;
|
|
22
|
-
content: ReactNode;
|
|
23
|
-
background: ReactNode;
|
|
24
|
-
contentRef: RefObject<HTMLDivElement>;
|
|
25
|
-
}>;
|
|
26
19
|
export {};
|
package/dist/SwipeAction.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwipeAction.js","sources":["../src/SwipeAction.tsx"],"sourcesContent":["'use client'\n\nimport type {\n\tCSSProperties,\n\tFunctionComponent,\n\tReactNode,\n\tRefObject,\n} from 'react'\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { useDrag } from 'react-use-drag'\nimport styles from './SwipeAction.module.css'\n\n// @TODO: add inertia\n// @TODO: animate snapping\n// @TODO: add threshold - maybe to react-use-drag\n\ntype OnLongSwipe = () => void\ntype Content = ReactNode\n\
|
|
1
|
+
{"version":3,"file":"SwipeAction.js","sources":["../src/SwipeAction.tsx"],"sourcesContent":["'use client'\n\nimport type {\n\tCSSProperties,\n\tFunctionComponent,\n\tReactNode,\n\tRefObject,\n} from 'react'\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { useDrag } from 'react-use-drag'\nimport styles from './SwipeAction.module.css'\n\n// @TODO: add inertia\n// @TODO: animate snapping\n// @TODO: add threshold - maybe to react-use-drag\n\ntype OnLongSwipe = () => void\ntype Content = ReactNode\n\nexport type Action = {\n\tbackground?: ReactNode\n\tcontent?: Content\n\tonLongSwipe?: OnLongSwipe\n} & (\n\t| {\n\t\t\tcontent: Content\n\t }\n\t| {\n\t\t\tonLongSwipe: OnLongSwipe\n\t }\n)\n\nexport type SwipeActionProps = {\n\tmain: (handle: ReactNode) => ReactNode\n\tstartAction?: Action\n\tendAction?: Action\n}\n\nexport const SwipeAction: FunctionComponent<SwipeActionProps> = ({\n\tstartAction,\n\tendAction,\n\tmain,\n}) => {\n\tconst [position, setPosition] = useState(0)\n\tconst [positionOffset, setPositionOffset] = useState(0)\n\tconst [isSwiping, setIsSwiping] = useState(false)\n\tconst onRelativePositionChange = useCallback((x: number) => {\n\t\tif (Math.abs(x) > 5) {\n\t\t\tsetIsSwiping(true)\n\t\t}\n\t\tsetPositionOffset(x)\n\t}, [])\n\tconst isLongSwipeEnabled = useRef(true) // Prevents long swipe from being triggered twice in React strict mode\n\tconst onEnd = useCallback(\n\t\t(x: number) => {\n\t\t\tif (x === 0) {\n\t\t\t\tsetIsSwiping(false)\n\t\t\t} else {\n\t\t\t\tsetPosition((position) => {\n\t\t\t\t\tconst newPosition = position + x\n\t\t\t\t\tconst mainWidth = mainRef.current?.offsetWidth ?? 0\n\n\t\t\t\t\tconst handleContent = (\n\t\t\t\t\t\tref: RefObject<HTMLDivElement>,\n\t\t\t\t\t\tposition: Position,\n\t\t\t\t\t\tonLongSwipe: undefined | OnLongSwipe,\n\t\t\t\t\t) => {\n\t\t\t\t\t\tconst contentWidth = ref.current?.offsetWidth\n\t\t\t\t\t\tconst positionSign = position === 'start' ? 1 : -1\n\t\t\t\t\t\tconst normalizedSwipePosition = positionSign * newPosition\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tonLongSwipe &&\n\t\t\t\t\t\t\tcontentWidth !== undefined &&\n\t\t\t\t\t\t\tnormalizedSwipePosition >\n\t\t\t\t\t\t\t\tMath.max(mainWidth / 4, contentWidth) * 1.6\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tif (isLongSwipeEnabled.current) {\n\t\t\t\t\t\t\t\tonLongSwipe()\n\t\t\t\t\t\t\t\tisLongSwipeEnabled.current = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn positionSign * mainWidth\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tcontentWidth !== 0 &&\n\t\t\t\t\t\t\tcontentWidth !== undefined &&\n\t\t\t\t\t\t\tnormalizedSwipePosition > contentWidth * 0.7\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn positionSign * contentWidth\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Math.sign(newPosition) === positionSign) {\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\tsetIsSwiping(false)\n\t\t\t\t\t\t\t}, 200) // Delay to ignore immediate click\n\t\t\t\t\t\t\treturn 0\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\thandleContent(\n\t\t\t\t\t\t\tstartActionContentRef,\n\t\t\t\t\t\t\t'start',\n\t\t\t\t\t\t\tstartAction?.onLongSwipe,\n\t\t\t\t\t\t) ??\n\t\t\t\t\t\thandleContent(endActionContentRef, 'end', endAction?.onLongSwipe) ??\n\t\t\t\t\t\tnewPosition\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t}\n\t\t\tsetPositionOffset(0)\n\t\t},\n\t\t[startAction?.onLongSwipe, endAction?.onLongSwipe],\n\t)\n\tconst onStart = useCallback(() => {\n\t\tisLongSwipeEnabled.current = true\n\t}, [])\n\tconst { elementProps } = useDrag({\n\t\tonStart,\n\t\tonRelativePositionChange,\n\t\tonEnd,\n\t})\n\tconst mainRef = useRef<HTMLDivElement>(null)\n\tconst startActionContentRef = useRef<HTMLDivElement>(null)\n\tconst endActionContentRef = useRef<HTMLDivElement>(null)\n\n\tconst x = useMemo(\n\t\t() =>\n\t\t\tMath.max(\n\t\t\t\tendAction ? Number.NEGATIVE_INFINITY : 0,\n\t\t\t\tMath.min(\n\t\t\t\t\tstartAction ? Number.POSITIVE_INFINITY : 0,\n\t\t\t\t\tposition + positionOffset,\n\t\t\t\t),\n\t\t\t),\n\t\t[position, positionOffset, startAction, endAction],\n\t)\n\n\treturn (\n\t\t<div className={styles.wrapper}>\n\t\t\t{startAction && x > 0 && (\n\t\t\t\t<Action\n\t\t\t\t\tposition=\"start\"\n\t\t\t\t\tcontent={startAction.content}\n\t\t\t\t\tbackground={startAction.background}\n\t\t\t\t\tcontentRef={startActionContentRef}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{endAction && x < 0 && (\n\t\t\t\t<Action\n\t\t\t\t\tposition=\"end\"\n\t\t\t\t\tcontent={endAction.content}\n\t\t\t\t\tbackground={endAction.background}\n\t\t\t\t\tcontentRef={endActionContentRef}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={styles.main}\n\t\t\t\tref={mainRef}\n\t\t\t\tstyle={\n\t\t\t\t\t{\n\t\t\t\t\t\t'--x': `${x}px`,\n\t\t\t\t\t} as CSSProperties\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t{main(\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={styles.handle}\n\t\t\t\t\t\t{...elementProps}\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tif (isSwiping) {\n\t\t\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>,\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\ntype Position = 'start' | 'end'\n\nconst Action: FunctionComponent<{\n\tposition: Position\n\tcontent: ReactNode\n\tbackground: ReactNode\n\tcontentRef: RefObject<HTMLDivElement>\n}> = ({ content, background, position, contentRef }) => {\n\t// @TODO: allow focus by tab key before visible\n\treturn (\n\t\t<div className={`${styles.action} ${styles[`is_position_${position}`]}`}>\n\t\t\t<div className={styles.action_background}>{background}</div>\n\t\t\t<div className={styles.action_content} ref={contentRef}>\n\t\t\t\t{content}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],"names":[],"mappings":";;;;;;;AAsCO;AACN;;;;AAOA;;;;;;;AAOA;AAEE;;;;;;AAIE;;AAGA;;;AAMC;AACA;AACA;AAEC;;AAEC;AAED;AACC;AACA;;;;;AAMD;AACA;;;;AAKA;;AAEA;AACA;;AAEF;AAEA;AASD;;;AAGF;;AAIA;;;AAGA;AACA;AACA;AACA;AACD;AACA;AACA;;AAIE;;AAUF;;AAwBsB;;;;AAWjB;AAMN;AAIA;;;AAOC;AAQD;;"}
|