@chayns-components/swipeable-wrapper 5.0.0-beta.1000

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.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -0
  3. package/lib/cjs/components/swipeable-wrapper/SwipeableWrapper.js +188 -0
  4. package/lib/cjs/components/swipeable-wrapper/SwipeableWrapper.js.map +1 -0
  5. package/lib/cjs/components/swipeable-wrapper/SwipeableWrapper.styles.js +18 -0
  6. package/lib/cjs/components/swipeable-wrapper/SwipeableWrapper.styles.js.map +1 -0
  7. package/lib/cjs/components/swipeable-wrapper/swipeable-action/SwipeableAction.js +115 -0
  8. package/lib/cjs/components/swipeable-wrapper/swipeable-action/SwipeableAction.js.map +1 -0
  9. package/lib/cjs/components/swipeable-wrapper/swipeable-action/SwipeableAction.styles.js +56 -0
  10. package/lib/cjs/components/swipeable-wrapper/swipeable-action/SwipeableAction.styles.js.map +1 -0
  11. package/lib/cjs/index.js +14 -0
  12. package/lib/cjs/index.js.map +1 -0
  13. package/lib/cjs/utils/threshold.js +14 -0
  14. package/lib/cjs/utils/threshold.js.map +1 -0
  15. package/lib/esm/components/swipeable-wrapper/SwipeableWrapper.js +177 -0
  16. package/lib/esm/components/swipeable-wrapper/SwipeableWrapper.js.map +1 -0
  17. package/lib/esm/components/swipeable-wrapper/SwipeableWrapper.styles.js +11 -0
  18. package/lib/esm/components/swipeable-wrapper/SwipeableWrapper.styles.js.map +1 -0
  19. package/lib/esm/components/swipeable-wrapper/swipeable-action/SwipeableAction.js +109 -0
  20. package/lib/esm/components/swipeable-wrapper/swipeable-action/SwipeableAction.js.map +1 -0
  21. package/lib/esm/components/swipeable-wrapper/swipeable-action/SwipeableAction.styles.js +58 -0
  22. package/lib/esm/components/swipeable-wrapper/swipeable-action/SwipeableAction.styles.js.map +1 -0
  23. package/lib/esm/index.js +2 -0
  24. package/lib/esm/index.js.map +1 -0
  25. package/lib/esm/utils/threshold.js +10 -0
  26. package/lib/esm/utils/threshold.js.map +1 -0
  27. package/lib/types/components/swipeable-wrapper/SwipeableWrapper.d.ts +29 -0
  28. package/lib/types/components/swipeable-wrapper/SwipeableWrapper.styles.d.ts +267 -0
  29. package/lib/types/components/swipeable-wrapper/swipeable-action/SwipeableAction.d.ts +16 -0
  30. package/lib/types/components/swipeable-wrapper/swipeable-action/SwipeableAction.styles.d.ts +275 -0
  31. package/lib/types/index.d.ts +1 -0
  32. package/lib/types/utils/threshold.d.ts +7 -0
  33. package/package.json +85 -0
@@ -0,0 +1,177 @@
1
+ import { vibrate } from 'chayns-api';
2
+ import { animate, useMotionValue } from 'framer-motion';
3
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { calcThreshold } from '../../utils/threshold';
5
+ import SwipeableAction, { SWIPEABLE_ACTION_WIDTH } from './swipeable-action/SwipeableAction';
6
+ import { StyledMotionSwipeableWrapper, StyledSwipeableWrapperContent } from './SwipeableWrapper.styles';
7
+ const SwipeableWrapper = _ref => {
8
+ let {
9
+ children,
10
+ leftActions = [],
11
+ rightActions = [],
12
+ shouldUseOpacityAnimation
13
+ } = _ref;
14
+ const [leftThreshold, setLeftThreshold] = useState(calcThreshold({
15
+ actionCount: leftActions.length,
16
+ direction: 'left',
17
+ width: window.innerWidth
18
+ }));
19
+ const [rightThreshold, setRightThreshold] = useState(calcThreshold({
20
+ actionCount: rightActions.length,
21
+ direction: 'right',
22
+ width: window.innerWidth
23
+ }));
24
+ const swipeableWrapperRef = useRef(null);
25
+ const listItemXOffset = useMotionValue(0);
26
+ const close = useCallback(() => {
27
+ void animate(listItemXOffset, 0);
28
+ }, [listItemXOffset]);
29
+ const open = useCallback(direction => {
30
+ switch (direction) {
31
+ case 'left':
32
+ void animate(listItemXOffset, SWIPEABLE_ACTION_WIDTH * leftActions.length);
33
+ break;
34
+ case 'right':
35
+ void animate(listItemXOffset, -SWIPEABLE_ACTION_WIDTH * rightActions.length);
36
+ break;
37
+ default:
38
+ break;
39
+ }
40
+ }, [leftActions.length, listItemXOffset, rightActions.length]);
41
+ useEffect(() => {
42
+ const width = swipeableWrapperRef.current?.parentElement?.offsetWidth;
43
+
44
+ // This check was deliberately chosen because a width of 0 is also not permitted.
45
+ if (width) {
46
+ setLeftThreshold(calcThreshold({
47
+ actionCount: leftActions.length,
48
+ direction: 'left',
49
+ width
50
+ }));
51
+ setRightThreshold(calcThreshold({
52
+ actionCount: rightActions.length,
53
+ direction: 'right',
54
+ width
55
+ }));
56
+ }
57
+ }, [leftActions.length, rightActions.length]);
58
+
59
+ // Close an opened menu when anything outside it is tapped
60
+ useEffect(() => {
61
+ function closeCallback(event) {
62
+ const eventTarget = event.target;
63
+
64
+ // @ts-expect-error: Pretty sure that the event target is always a Node.
65
+ if (eventTarget && !swipeableWrapperRef.current?.contains(eventTarget)) {
66
+ close();
67
+ }
68
+ }
69
+ document.addEventListener('mousedown', closeCallback);
70
+ document.addEventListener('touchstart', closeCallback);
71
+ return () => {
72
+ document.removeEventListener('mousedown', closeCallback);
73
+ document.removeEventListener('touchstart', closeCallback);
74
+ };
75
+ }, [close]);
76
+
77
+ // Vibrate when the threshold is passed
78
+ useEffect(() => listItemXOffset.onChange(newValue => {
79
+ const previous = listItemXOffset.getPrevious();
80
+ if (!previous) {
81
+ return;
82
+ }
83
+ const hasCrossedLeftThreshold = previous < leftThreshold && newValue >= leftThreshold || previous > leftThreshold && newValue <= leftThreshold;
84
+ const hasCrossedRightThreshold = previous < rightThreshold && newValue >= rightThreshold || previous > rightThreshold && newValue <= rightThreshold;
85
+ if (hasCrossedLeftThreshold || hasCrossedRightThreshold) {
86
+ void vibrate({
87
+ iOSFeedbackVibration: 6,
88
+ pattern: [150]
89
+ });
90
+ }
91
+ }), [leftThreshold, listItemXOffset, rightThreshold]);
92
+ const handlePan = useCallback((_, info) => {
93
+ const currentXOffset = listItemXOffset.get();
94
+ const dampingFactor = info.offset.x > 0 && leftActions.length > 0 || info.offset.x < 0 && rightActions.length > 0 || currentXOffset > 0 && info.delta.x < 0 || currentXOffset < 0 && info.delta.x > 0 ? 1 : 0.75 / (Math.abs(info.offset.x) / 9);
95
+ if (Math.abs(info.offset.x) > 30 || currentXOffset > 0) {
96
+ listItemXOffset.set(currentXOffset + info.delta.x * dampingFactor);
97
+ }
98
+ }, [leftActions.length, listItemXOffset, rightActions.length]);
99
+ const handlePanEnd = useCallback(() => {
100
+ const offset = listItemXOffset.get();
101
+ if (offset > leftThreshold) {
102
+ leftActions[0]?.action();
103
+ close();
104
+ } else if (offset < rightThreshold) {
105
+ rightActions[rightActions.length - 1]?.action();
106
+ close();
107
+ } else {
108
+ let state;
109
+ if (offset > 2) {
110
+ state = 'left-open';
111
+ } else if (offset < -2) {
112
+ state = 'right-open';
113
+ } else {
114
+ state = 'closed';
115
+ }
116
+
117
+ // eslint-disable-next-line default-case
118
+ switch (state) {
119
+ case 'left-open':
120
+ if (offset < SWIPEABLE_ACTION_WIDTH) {
121
+ close();
122
+ } else {
123
+ open('left');
124
+ }
125
+ break;
126
+ case 'right-open':
127
+ if (offset > -SWIPEABLE_ACTION_WIDTH) {
128
+ close();
129
+ } else {
130
+ open('right');
131
+ }
132
+ break;
133
+ case 'closed':
134
+ if (offset > SWIPEABLE_ACTION_WIDTH) {
135
+ open('left');
136
+ } else if (offset < -SWIPEABLE_ACTION_WIDTH) {
137
+ open('right');
138
+ } else {
139
+ close();
140
+ }
141
+ }
142
+ }
143
+ }, [close, leftActions, leftThreshold, listItemXOffset, open, rightActions, rightThreshold]);
144
+ const leftActionElements = useMemo(() => Array.from(leftActions).reverse().map((item, index) => /*#__PURE__*/React.createElement(SwipeableAction, {
145
+ activationThreshold: leftThreshold,
146
+ close: close,
147
+ index: index,
148
+ item: item,
149
+ key: item.key,
150
+ listItemXOffset: listItemXOffset,
151
+ position: "left",
152
+ shouldUseOpacityAnimation: shouldUseOpacityAnimation,
153
+ totalActionCount: leftActions.length
154
+ })), [close, leftActions, leftThreshold, listItemXOffset, shouldUseOpacityAnimation]);
155
+ const rightActionElements = useMemo(() => rightActions.map((item, index) => /*#__PURE__*/React.createElement(SwipeableAction, {
156
+ activationThreshold: rightThreshold,
157
+ close: close,
158
+ index: index,
159
+ item: item,
160
+ key: item.key,
161
+ listItemXOffset: listItemXOffset,
162
+ position: "right",
163
+ shouldUseOpacityAnimation: shouldUseOpacityAnimation,
164
+ totalActionCount: rightActions.length
165
+ })), [rightActions, rightThreshold, close, listItemXOffset, shouldUseOpacityAnimation]);
166
+ return /*#__PURE__*/React.createElement(StyledMotionSwipeableWrapper, {
167
+ onPan: handlePan,
168
+ onPanEnd: handlePanEnd,
169
+ ref: swipeableWrapperRef,
170
+ style: {
171
+ x: listItemXOffset
172
+ }
173
+ }, leftActionElements, /*#__PURE__*/React.createElement(StyledSwipeableWrapperContent, null, children), rightActionElements);
174
+ };
175
+ SwipeableWrapper.displayName = 'SwipeableWrapper';
176
+ export default SwipeableWrapper;
177
+ //# sourceMappingURL=SwipeableWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwipeableWrapper.js","names":["vibrate","animate","useMotionValue","React","useCallback","useEffect","useMemo","useRef","useState","calcThreshold","SwipeableAction","SWIPEABLE_ACTION_WIDTH","StyledMotionSwipeableWrapper","StyledSwipeableWrapperContent","SwipeableWrapper","_ref","children","leftActions","rightActions","shouldUseOpacityAnimation","leftThreshold","setLeftThreshold","actionCount","length","direction","width","window","innerWidth","rightThreshold","setRightThreshold","swipeableWrapperRef","listItemXOffset","close","open","current","parentElement","offsetWidth","closeCallback","event","eventTarget","target","contains","document","addEventListener","removeEventListener","onChange","newValue","previous","getPrevious","hasCrossedLeftThreshold","hasCrossedRightThreshold","iOSFeedbackVibration","pattern","handlePan","_","info","currentXOffset","get","dampingFactor","offset","x","delta","Math","abs","set","handlePanEnd","action","state","leftActionElements","Array","from","reverse","map","item","index","createElement","activationThreshold","key","position","totalActionCount","rightActionElements","onPan","onPanEnd","ref","style","displayName"],"sources":["../../../../src/components/swipeable-wrapper/SwipeableWrapper.tsx"],"sourcesContent":["import { vibrate } from 'chayns-api';\nimport { animate, PanInfo, useMotionValue } from 'framer-motion';\nimport React, {\n CSSProperties,\n FC,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { calcThreshold } from '../../utils/threshold';\nimport SwipeableAction, { SWIPEABLE_ACTION_WIDTH } from './swipeable-action/SwipeableAction';\nimport {\n StyledMotionSwipeableWrapper,\n StyledSwipeableWrapperContent,\n} from './SwipeableWrapper.styles';\n\nexport type SwipeableActionItem = {\n action: VoidFunction;\n backgroundColor: CSSProperties['backgroundColor'];\n color: CSSProperties['color'];\n text?: ReactNode;\n icon: ReactNode;\n key: string;\n};\n\nexport type SwipeableWrapperProps = {\n /**\n * The content of the Swipeable item.\n */\n children: ReactNode;\n /**\n * The left-side actions, ordered from the left to the right.\n */\n leftActions?: SwipeableActionItem[];\n /**\n * The right-side actions, ordered from left to the right.\n */\n rightActions?: SwipeableActionItem[];\n /**\n * Whether the opacity should be animated when swiping in the actions.\n */\n shouldUseOpacityAnimation?: boolean;\n};\n\nconst SwipeableWrapper: FC<SwipeableWrapperProps> = ({\n children,\n leftActions = [],\n rightActions = [],\n shouldUseOpacityAnimation,\n}) => {\n const [leftThreshold, setLeftThreshold] = useState(\n calcThreshold({\n actionCount: leftActions.length,\n direction: 'left',\n width: window.innerWidth,\n }),\n );\n\n const [rightThreshold, setRightThreshold] = useState(\n calcThreshold({\n actionCount: rightActions.length,\n direction: 'right',\n width: window.innerWidth,\n }),\n );\n\n const swipeableWrapperRef = useRef<HTMLDivElement | null>(null);\n\n const listItemXOffset = useMotionValue(0);\n\n const close = useCallback(() => {\n void animate(listItemXOffset, 0);\n }, [listItemXOffset]);\n\n const open = useCallback(\n (direction: 'left' | 'right') => {\n switch (direction) {\n case 'left':\n void animate(listItemXOffset, SWIPEABLE_ACTION_WIDTH * leftActions.length);\n break;\n case 'right':\n void animate(listItemXOffset, -SWIPEABLE_ACTION_WIDTH * rightActions.length);\n break;\n default:\n break;\n }\n },\n [leftActions.length, listItemXOffset, rightActions.length],\n );\n\n useEffect(() => {\n const width = swipeableWrapperRef.current?.parentElement?.offsetWidth;\n\n // This check was deliberately chosen because a width of 0 is also not permitted.\n if (width) {\n setLeftThreshold(\n calcThreshold({\n actionCount: leftActions.length,\n direction: 'left',\n width,\n }),\n );\n\n setRightThreshold(\n calcThreshold({\n actionCount: rightActions.length,\n direction: 'right',\n width,\n }),\n );\n }\n }, [leftActions.length, rightActions.length]);\n\n // Close an opened menu when anything outside it is tapped\n useEffect(() => {\n function closeCallback(event: MouseEvent | TouchEvent) {\n const eventTarget = event.target;\n\n // @ts-expect-error: Pretty sure that the event target is always a Node.\n if (eventTarget && !swipeableWrapperRef.current?.contains(eventTarget)) {\n close();\n }\n }\n\n document.addEventListener('mousedown', closeCallback);\n document.addEventListener('touchstart', closeCallback);\n\n return () => {\n document.removeEventListener('mousedown', closeCallback);\n document.removeEventListener('touchstart', closeCallback);\n };\n }, [close]);\n\n // Vibrate when the threshold is passed\n useEffect(\n () =>\n listItemXOffset.onChange((newValue: number) => {\n const previous = listItemXOffset.getPrevious();\n\n if (!previous) {\n return;\n }\n\n const hasCrossedLeftThreshold =\n (previous < leftThreshold && newValue >= leftThreshold) ||\n (previous > leftThreshold && newValue <= leftThreshold);\n\n const hasCrossedRightThreshold =\n (previous < rightThreshold && newValue >= rightThreshold) ||\n (previous > rightThreshold && newValue <= rightThreshold);\n\n if (hasCrossedLeftThreshold || hasCrossedRightThreshold) {\n void vibrate({ iOSFeedbackVibration: 6, pattern: [150] });\n }\n }),\n [leftThreshold, listItemXOffset, rightThreshold],\n );\n\n const handlePan = useCallback(\n (_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n const currentXOffset = listItemXOffset.get();\n\n const dampingFactor =\n (info.offset.x > 0 && leftActions.length > 0) ||\n (info.offset.x < 0 && rightActions.length > 0) ||\n (currentXOffset > 0 && info.delta.x < 0) ||\n (currentXOffset < 0 && info.delta.x > 0)\n ? 1\n : 0.75 / (Math.abs(info.offset.x) / 9);\n\n if (Math.abs(info.offset.x) > 30 || currentXOffset > 0) {\n listItemXOffset.set(currentXOffset + info.delta.x * dampingFactor);\n }\n },\n [leftActions.length, listItemXOffset, rightActions.length],\n );\n\n const handlePanEnd = useCallback(() => {\n const offset = listItemXOffset.get();\n\n if (offset > leftThreshold) {\n leftActions[0]?.action();\n close();\n } else if (offset < rightThreshold) {\n rightActions[rightActions.length - 1]?.action();\n close();\n } else {\n let state: 'left-open' | 'right-open' | 'closed';\n\n if (offset > 2) {\n state = 'left-open';\n } else if (offset < -2) {\n state = 'right-open';\n } else {\n state = 'closed';\n }\n\n // eslint-disable-next-line default-case\n switch (state) {\n case 'left-open':\n if (offset < SWIPEABLE_ACTION_WIDTH) {\n close();\n } else {\n open('left');\n }\n break;\n case 'right-open':\n if (offset > -SWIPEABLE_ACTION_WIDTH) {\n close();\n } else {\n open('right');\n }\n break;\n case 'closed':\n if (offset > SWIPEABLE_ACTION_WIDTH) {\n open('left');\n } else if (offset < -SWIPEABLE_ACTION_WIDTH) {\n open('right');\n } else {\n close();\n }\n }\n }\n }, [close, leftActions, leftThreshold, listItemXOffset, open, rightActions, rightThreshold]);\n\n const leftActionElements = useMemo(\n () =>\n Array.from(leftActions)\n .reverse()\n .map((item, index) => (\n <SwipeableAction\n activationThreshold={leftThreshold}\n close={close}\n index={index}\n item={item}\n key={item.key}\n listItemXOffset={listItemXOffset}\n position=\"left\"\n shouldUseOpacityAnimation={shouldUseOpacityAnimation}\n totalActionCount={leftActions.length}\n />\n )),\n [close, leftActions, leftThreshold, listItemXOffset, shouldUseOpacityAnimation],\n );\n\n const rightActionElements = useMemo(\n () =>\n rightActions.map((item, index) => (\n <SwipeableAction\n activationThreshold={rightThreshold}\n close={close}\n index={index}\n item={item}\n key={item.key}\n listItemXOffset={listItemXOffset}\n position=\"right\"\n shouldUseOpacityAnimation={shouldUseOpacityAnimation}\n totalActionCount={rightActions.length}\n />\n )),\n [rightActions, rightThreshold, close, listItemXOffset, shouldUseOpacityAnimation],\n );\n\n return (\n <StyledMotionSwipeableWrapper\n onPan={handlePan}\n onPanEnd={handlePanEnd}\n ref={swipeableWrapperRef}\n style={{ x: listItemXOffset }}\n >\n {leftActionElements}\n <StyledSwipeableWrapperContent>{children}</StyledSwipeableWrapperContent>\n {rightActionElements}\n </StyledMotionSwipeableWrapper>\n );\n};\n\nSwipeableWrapper.displayName = 'SwipeableWrapper';\n\nexport default SwipeableWrapper;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { motion } from 'framer-motion';
2
+ import styled from 'styled-components';
3
+ export const StyledMotionSwipeableWrapper = styled(motion.div)`
4
+ position: relative;
5
+ touch-action: pan-y;
6
+ user-select: none;
7
+ `;
8
+ export const StyledSwipeableWrapperContent = styled.div`
9
+ width: 100%;
10
+ `;
11
+ //# sourceMappingURL=SwipeableWrapper.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwipeableWrapper.styles.js","names":["motion","styled","StyledMotionSwipeableWrapper","div","StyledSwipeableWrapperContent"],"sources":["../../../../src/components/swipeable-wrapper/SwipeableWrapper.styles.ts"],"sourcesContent":["import type { FramerMotionBugFix } from '@chayns-components/core';\nimport { motion } from 'framer-motion';\nimport styled from 'styled-components';\n\nexport const StyledMotionSwipeableWrapper = styled(motion.div)<FramerMotionBugFix>`\n position: relative;\n touch-action: pan-y;\n user-select: none;\n`;\n\nexport const StyledSwipeableWrapperContent = styled.div`\n width: 100%;\n`;\n"],"mappings":"AACA,SAASA,MAAM,QAAQ,eAAe;AACtC,OAAOC,MAAM,MAAM,mBAAmB;AAEtC,OAAO,MAAMC,4BAA4B,GAAGD,MAAM,CAACD,MAAM,CAACG,GAAG,CAAqB;AAClF;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,6BAA6B,GAAGH,MAAM,CAACE,GAAG;AACvD;AACA,CAAC","ignoreList":[]}
@@ -0,0 +1,109 @@
1
+ import { useMotionValueEvent, useSpring, useTransform } from 'framer-motion';
2
+ import React, { useEffect } from 'react';
3
+ import { StyledMotionSwipeableAction, StyledSwipeableActionButton } from './SwipeableAction.styles';
4
+ export const SWIPEABLE_ACTION_WIDTH = 72;
5
+ const SwipeableAction = _ref => {
6
+ let {
7
+ activationThreshold,
8
+ close,
9
+ index,
10
+ item,
11
+ listItemXOffset,
12
+ position,
13
+ shouldUseOpacityAnimation,
14
+ totalActionCount
15
+ } = _ref;
16
+ const [pointerEvents, setPointerEvents] = React.useState('none');
17
+ const handleButtonClick = () => {
18
+ item.action();
19
+ close();
20
+ };
21
+
22
+ /**
23
+ * By default, the action sticks to the content of the swipeable item. This
24
+ * makes it move outwards to reveal the inner items.
25
+ */
26
+ const actionOffset = useTransform(listItemXOffset, newValue => {
27
+ const maxOffset = SWIPEABLE_ACTION_WIDTH * index;
28
+ const fractionalOffset = -newValue / totalActionCount * index;
29
+ switch (position) {
30
+ case 'left':
31
+ return Math.max(-maxOffset, fractionalOffset);
32
+ case 'right':
33
+ return Math.min(maxOffset, fractionalOffset);
34
+ default:
35
+ return 0;
36
+ }
37
+ });
38
+
39
+ /**
40
+ * Brings the item in again if past the threshold. Only relevant for
41
+ * outermost items.
42
+ */
43
+ const actionOverlayOffset = useSpring(0, {
44
+ bounce: 0
45
+ });
46
+
47
+ /**
48
+ * Combines the two values above to create the correct X transform that has
49
+ * to be applied to the action.
50
+ */
51
+ const actionX = useTransform([actionOffset, actionOverlayOffset], _ref2 => {
52
+ let [x, y] = _ref2;
53
+ if (position === 'left') {
54
+ return Math.min((x ?? 0) + (y ?? 0), 0);
55
+ }
56
+ return Math.max((x ?? 0) + (y ?? 0), 0);
57
+ });
58
+ const opacity = useTransform(listItemXOffset, x => Math.max(0, Math.min(1, Math.abs(x) / 72)));
59
+ useMotionValueEvent(opacity, 'change', value => {
60
+ setPointerEvents(value < 0.5 ? 'none' : 'auto');
61
+ });
62
+
63
+ // Animate to the middle after passing threshold if outermost item
64
+ useEffect(() => {
65
+ const isOuterMost = index === totalActionCount - 1;
66
+ if (!isOuterMost) return undefined;
67
+ return listItemXOffset.onChange(newValue => {
68
+ const lastValue = listItemXOffset.getPrevious();
69
+ if (!lastValue) {
70
+ return;
71
+ }
72
+
73
+ // eslint-disable-next-line default-case
74
+ switch (position) {
75
+ case 'left':
76
+ if (newValue > activationThreshold && lastValue <= activationThreshold) {
77
+ actionOverlayOffset.set(SWIPEABLE_ACTION_WIDTH * index);
78
+ } else if (newValue < activationThreshold && lastValue >= activationThreshold) {
79
+ actionOverlayOffset.set(0);
80
+ }
81
+ break;
82
+ case 'right':
83
+ if (newValue < activationThreshold && lastValue >= activationThreshold) {
84
+ actionOverlayOffset.set(SWIPEABLE_ACTION_WIDTH * -1 * index);
85
+ } else if (newValue > activationThreshold && lastValue <= activationThreshold) {
86
+ actionOverlayOffset.set(0);
87
+ }
88
+ }
89
+ });
90
+ }, [actionOverlayOffset, activationThreshold, index, listItemXOffset, position, totalActionCount]);
91
+ return /*#__PURE__*/React.createElement(StyledMotionSwipeableAction, {
92
+ $backgroundColor: item.backgroundColor,
93
+ $position: position,
94
+ style: {
95
+ x: actionX,
96
+ opacity: shouldUseOpacityAnimation ? opacity : 1
97
+ }
98
+ }, /*#__PURE__*/React.createElement(StyledSwipeableActionButton, {
99
+ onClick: handleButtonClick,
100
+ style: {
101
+ pointerEvents
102
+ },
103
+ $color: item.color,
104
+ $width: `${SWIPEABLE_ACTION_WIDTH}px`
105
+ }, item.icon, item.text));
106
+ };
107
+ SwipeableAction.displayName = 'SwipeableAction';
108
+ export default SwipeableAction;
109
+ //# sourceMappingURL=SwipeableAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwipeableAction.js","names":["useMotionValueEvent","useSpring","useTransform","React","useEffect","StyledMotionSwipeableAction","StyledSwipeableActionButton","SWIPEABLE_ACTION_WIDTH","SwipeableAction","_ref","activationThreshold","close","index","item","listItemXOffset","position","shouldUseOpacityAnimation","totalActionCount","pointerEvents","setPointerEvents","useState","handleButtonClick","action","actionOffset","newValue","maxOffset","fractionalOffset","Math","max","min","actionOverlayOffset","bounce","actionX","_ref2","x","y","opacity","abs","value","isOuterMost","undefined","onChange","lastValue","getPrevious","set","createElement","$backgroundColor","backgroundColor","$position","style","onClick","$color","color","$width","icon","text","displayName"],"sources":["../../../../../src/components/swipeable-wrapper/swipeable-action/SwipeableAction.tsx"],"sourcesContent":["import { MotionValue, useMotionValueEvent, useSpring, useTransform } from 'framer-motion';\nimport React, { FC, useEffect } from 'react';\nimport type { SwipeableActionItem } from '../SwipeableWrapper';\nimport { StyledMotionSwipeableAction, StyledSwipeableActionButton } from './SwipeableAction.styles';\n\nexport const SWIPEABLE_ACTION_WIDTH = 72;\n\nexport type SwipeableActionProps = {\n activationThreshold: number;\n close: VoidFunction;\n index: number;\n item: SwipeableActionItem;\n listItemXOffset: MotionValue<number>;\n position: 'left' | 'right';\n shouldUseOpacityAnimation?: boolean;\n totalActionCount: number;\n};\n\nconst SwipeableAction: FC<SwipeableActionProps> = ({\n activationThreshold,\n close,\n index,\n item,\n listItemXOffset,\n position,\n shouldUseOpacityAnimation,\n totalActionCount,\n}) => {\n const [pointerEvents, setPointerEvents] = React.useState<'auto' | 'none'>('none');\n\n const handleButtonClick = () => {\n item.action();\n close();\n };\n\n /**\n * By default, the action sticks to the content of the swipeable item. This\n * makes it move outwards to reveal the inner items.\n */\n const actionOffset = useTransform(listItemXOffset, (newValue) => {\n const maxOffset = SWIPEABLE_ACTION_WIDTH * index;\n const fractionalOffset = (-newValue / totalActionCount) * index;\n\n switch (position) {\n case 'left':\n return Math.max(-maxOffset, fractionalOffset);\n case 'right':\n return Math.min(maxOffset, fractionalOffset);\n default:\n return 0;\n }\n });\n\n /**\n * Brings the item in again if past the threshold. Only relevant for\n * outermost items.\n */\n const actionOverlayOffset = useSpring(0, {\n bounce: 0,\n }) as MotionValue<number>;\n\n /**\n * Combines the two values above to create the correct X transform that has\n * to be applied to the action.\n */\n const actionX = useTransform<number, number>([actionOffset, actionOverlayOffset], ([x, y]) => {\n if (position === 'left') {\n return Math.min((x ?? 0) + (y ?? 0), 0);\n }\n\n return Math.max((x ?? 0) + (y ?? 0), 0);\n });\n\n const opacity = useTransform(listItemXOffset, (x) =>\n Math.max(0, Math.min(1, Math.abs(x) / 72)),\n );\n\n useMotionValueEvent(opacity, 'change', (value) => {\n setPointerEvents(value < 0.5 ? 'none' : 'auto');\n });\n\n // Animate to the middle after passing threshold if outermost item\n useEffect(() => {\n const isOuterMost = index === totalActionCount - 1;\n\n if (!isOuterMost) return undefined;\n\n return listItemXOffset.onChange((newValue) => {\n const lastValue = listItemXOffset.getPrevious();\n\n if (!lastValue) {\n return;\n }\n\n // eslint-disable-next-line default-case\n switch (position) {\n case 'left':\n if (newValue > activationThreshold && lastValue <= activationThreshold) {\n actionOverlayOffset.set(SWIPEABLE_ACTION_WIDTH * index);\n } else if (newValue < activationThreshold && lastValue >= activationThreshold) {\n actionOverlayOffset.set(0);\n }\n break;\n case 'right':\n if (newValue < activationThreshold && lastValue >= activationThreshold) {\n actionOverlayOffset.set(SWIPEABLE_ACTION_WIDTH * -1 * index);\n } else if (newValue > activationThreshold && lastValue <= activationThreshold) {\n actionOverlayOffset.set(0);\n }\n }\n });\n }, [\n actionOverlayOffset,\n activationThreshold,\n index,\n listItemXOffset,\n position,\n totalActionCount,\n ]);\n\n return (\n <StyledMotionSwipeableAction\n $backgroundColor={item.backgroundColor}\n $position={position}\n style={{ x: actionX, opacity: shouldUseOpacityAnimation ? opacity : 1 }}\n >\n <StyledSwipeableActionButton\n onClick={handleButtonClick}\n style={{ pointerEvents }}\n $color={item.color}\n $width={`${SWIPEABLE_ACTION_WIDTH}px`}\n >\n {item.icon}\n {item.text}\n </StyledSwipeableActionButton>\n </StyledMotionSwipeableAction>\n );\n};\n\nSwipeableAction.displayName = 'SwipeableAction';\n\nexport default SwipeableAction;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,58 @@
1
+ import { motion } from 'framer-motion';
2
+ import styled, { css } from 'styled-components';
3
+ export const StyledMotionSwipeableAction = styled(motion.div)`
4
+ background-color: ${_ref => {
5
+ let {
6
+ $backgroundColor
7
+ } = _ref;
8
+ return $backgroundColor;
9
+ }};
10
+ display: flex;
11
+ height: 100%;
12
+ position: absolute;
13
+ top: 0;
14
+ width: 200vw;
15
+
16
+ ${_ref2 => {
17
+ let {
18
+ $position
19
+ } = _ref2;
20
+ if ($position === 'left') {
21
+ return css`
22
+ justify-content: flex-end;
23
+ right: 100%;
24
+ `;
25
+ }
26
+ return css`
27
+ justify-content: flex-start;
28
+ left: 100%;
29
+ `;
30
+ }}
31
+ `;
32
+ export const StyledSwipeableActionButton = styled.button`
33
+ align-items: center;
34
+ appearance: none;
35
+ background: none;
36
+ box-shadow: none;
37
+ color: ${_ref3 => {
38
+ let {
39
+ $color
40
+ } = _ref3;
41
+ return $color;
42
+ }};
43
+ display: flex;
44
+ flex-direction: column;
45
+ font-size: 88%;
46
+ gap: 4px;
47
+ height: 100%;
48
+ justify-content: center;
49
+ margin: 0;
50
+ padding: 0;
51
+ width: ${_ref4 => {
52
+ let {
53
+ $width
54
+ } = _ref4;
55
+ return $width;
56
+ }};
57
+ `;
58
+ //# sourceMappingURL=SwipeableAction.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwipeableAction.styles.js","names":["motion","styled","css","StyledMotionSwipeableAction","div","_ref","$backgroundColor","_ref2","$position","StyledSwipeableActionButton","button","_ref3","$color","_ref4","$width"],"sources":["../../../../../src/components/swipeable-wrapper/swipeable-action/SwipeableAction.styles.ts"],"sourcesContent":["import { motion } from 'framer-motion';\nimport type { CSSProperties } from 'react';\nimport styled, { css } from 'styled-components';\n\ntype StyledSwipeableActionProps = {\n $position: 'left' | 'right';\n $backgroundColor: CSSProperties['backgroundColor'];\n};\n\nexport const StyledMotionSwipeableAction = styled(motion.div)<StyledSwipeableActionProps>`\n background-color: ${({ $backgroundColor }) => $backgroundColor};\n display: flex;\n height: 100%;\n position: absolute;\n top: 0;\n width: 200vw;\n\n ${({ $position }) => {\n if ($position === 'left') {\n return css`\n justify-content: flex-end;\n right: 100%;\n `;\n }\n return css`\n justify-content: flex-start;\n left: 100%;\n `;\n }}\n`;\n\ntype StyledSwipeableActionButtonsProps = {\n $width: CSSProperties['width'];\n $color: CSSProperties['color'];\n};\n\nexport const StyledSwipeableActionButton = styled.button<StyledSwipeableActionButtonsProps>`\n align-items: center;\n appearance: none;\n background: none;\n box-shadow: none;\n color: ${({ $color }) => $color};\n display: flex;\n flex-direction: column;\n font-size: 88%;\n gap: 4px;\n height: 100%;\n justify-content: center;\n margin: 0;\n padding: 0;\n width: ${({ $width }) => $width};\n`;\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,eAAe;AAEtC,OAAOC,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAO/C,OAAO,MAAMC,2BAA2B,GAAGF,MAAM,CAACD,MAAM,CAACI,GAAG,CAA6B;AACzF,wBAAwBC,IAAA;EAAA,IAAC;IAAEC;EAAiB,CAAC,GAAAD,IAAA;EAAA,OAAKC,gBAAgB;AAAA;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,KAAA,IAAmB;EAAA,IAAlB;IAAEC;EAAU,CAAC,GAAAD,KAAA;EACZ,IAAIC,SAAS,KAAK,MAAM,EAAE;IACtB,OAAON,GAAG;AACtB;AACA;AACA,aAAa;EACL;EACA,OAAOA,GAAG;AAClB;AACA;AACA,SAAS;AACL,CAAC;AACL,CAAC;AAOD,OAAO,MAAMO,2BAA2B,GAAGR,MAAM,CAACS,MAAyC;AAC3F;AACA;AACA;AACA;AACA,aAAaC,KAAA;EAAA,IAAC;IAAEC;EAAO,CAAC,GAAAD,KAAA;EAAA,OAAKC,MAAM;AAAA;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAaC,KAAA;EAAA,IAAC;IAAEC;EAAO,CAAC,GAAAD,KAAA;EAAA,OAAKC,MAAM;AAAA;AACnC,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export { default as SwipeableWrapper } from './components/swipeable-wrapper/SwipeableWrapper';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["default","SwipeableWrapper"],"sources":["../../src/index.ts"],"sourcesContent":["export { default as SwipeableWrapper } from './components/swipeable-wrapper/SwipeableWrapper';\n"],"mappings":"AAAA,SAASA,OAAO,IAAIC,gBAAgB,QAAQ,iDAAiD","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ import { SWIPEABLE_ACTION_WIDTH } from '../components/swipeable-wrapper/swipeable-action/SwipeableAction';
2
+ export const calcThreshold = _ref => {
3
+ let {
4
+ actionCount,
5
+ direction,
6
+ width
7
+ } = _ref;
8
+ return Math.max(width / 2, SWIPEABLE_ACTION_WIDTH * actionCount) * (direction === 'left' ? 1 : -1);
9
+ };
10
+ //# sourceMappingURL=threshold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threshold.js","names":["SWIPEABLE_ACTION_WIDTH","calcThreshold","_ref","actionCount","direction","width","Math","max"],"sources":["../../../src/utils/threshold.ts"],"sourcesContent":["import { SWIPEABLE_ACTION_WIDTH } from '../components/swipeable-wrapper/swipeable-action/SwipeableAction';\n\ninterface CalcThresholdOptions {\n actionCount: number;\n direction: 'left' | 'right';\n width: number;\n}\n\nexport const calcThreshold = ({ actionCount, direction, width }: CalcThresholdOptions) =>\n Math.max(width / 2, SWIPEABLE_ACTION_WIDTH * actionCount) * (direction === 'left' ? 1 : -1);\n"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,kEAAkE;AAQzG,OAAO,MAAMC,aAAa,GAAGC,IAAA;EAAA,IAAC;IAAEC,WAAW;IAAEC,SAAS;IAAEC;EAA4B,CAAC,GAAAH,IAAA;EAAA,OACjFI,IAAI,CAACC,GAAG,CAACF,KAAK,GAAG,CAAC,EAAEL,sBAAsB,GAAGG,WAAW,CAAC,IAAIC,SAAS,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAAA","ignoreList":[]}
@@ -0,0 +1,29 @@
1
+ import { CSSProperties, FC, ReactNode } from 'react';
2
+ export type SwipeableActionItem = {
3
+ action: VoidFunction;
4
+ backgroundColor: CSSProperties['backgroundColor'];
5
+ color: CSSProperties['color'];
6
+ text?: ReactNode;
7
+ icon: ReactNode;
8
+ key: string;
9
+ };
10
+ export type SwipeableWrapperProps = {
11
+ /**
12
+ * The content of the Swipeable item.
13
+ */
14
+ children: ReactNode;
15
+ /**
16
+ * The left-side actions, ordered from the left to the right.
17
+ */
18
+ leftActions?: SwipeableActionItem[];
19
+ /**
20
+ * The right-side actions, ordered from left to the right.
21
+ */
22
+ rightActions?: SwipeableActionItem[];
23
+ /**
24
+ * Whether the opacity should be animated when swiping in the actions.
25
+ */
26
+ shouldUseOpacityAnimation?: boolean;
27
+ };
28
+ declare const SwipeableWrapper: FC<SwipeableWrapperProps>;
29
+ export default SwipeableWrapper;