react-native-hold-menu-actions 0.1.6

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 (219) hide show
  1. package/LICENCE +21 -0
  2. package/README.md +38 -0
  3. package/lib/commonjs/components/backdrop/Backdrop.js +104 -0
  4. package/lib/commonjs/components/backdrop/Backdrop.js.map +1 -0
  5. package/lib/commonjs/components/backdrop/constants.js +14 -0
  6. package/lib/commonjs/components/backdrop/constants.js.map +1 -0
  7. package/lib/commonjs/components/backdrop/index.js +16 -0
  8. package/lib/commonjs/components/backdrop/index.js.map +1 -0
  9. package/lib/commonjs/components/backdrop/styles.js +17 -0
  10. package/lib/commonjs/components/backdrop/styles.js.map +1 -0
  11. package/lib/commonjs/components/flatList/FlatList.js +35 -0
  12. package/lib/commonjs/components/flatList/FlatList.js.map +1 -0
  13. package/lib/commonjs/components/flatList/index.js +16 -0
  14. package/lib/commonjs/components/flatList/index.js.map +1 -0
  15. package/lib/commonjs/components/holdItem/HoldItem.js +369 -0
  16. package/lib/commonjs/components/holdItem/HoldItem.js.map +1 -0
  17. package/lib/commonjs/components/holdItem/index.js +16 -0
  18. package/lib/commonjs/components/holdItem/index.js.map +1 -0
  19. package/lib/commonjs/components/holdItem/styles.js +22 -0
  20. package/lib/commonjs/components/holdItem/styles.js.map +1 -0
  21. package/lib/commonjs/components/holdItem/types.d.js +2 -0
  22. package/lib/commonjs/components/holdItem/types.d.js.map +1 -0
  23. package/lib/commonjs/components/icon/Icon.js +43 -0
  24. package/lib/commonjs/components/icon/Icon.js.map +1 -0
  25. package/lib/commonjs/components/icon/index.js +16 -0
  26. package/lib/commonjs/components/icon/index.js.map +1 -0
  27. package/lib/commonjs/components/menu/Menu.js +57 -0
  28. package/lib/commonjs/components/menu/Menu.js.map +1 -0
  29. package/lib/commonjs/components/menu/MenuItem.js +85 -0
  30. package/lib/commonjs/components/menu/MenuItem.js.map +1 -0
  31. package/lib/commonjs/components/menu/MenuItems.js +35 -0
  32. package/lib/commonjs/components/menu/MenuItems.js.map +1 -0
  33. package/lib/commonjs/components/menu/MenuList.js +121 -0
  34. package/lib/commonjs/components/menu/MenuList.js.map +1 -0
  35. package/lib/commonjs/components/menu/Separator.js +47 -0
  36. package/lib/commonjs/components/menu/Separator.js.map +1 -0
  37. package/lib/commonjs/components/menu/calculations.js +31 -0
  38. package/lib/commonjs/components/menu/calculations.js.map +1 -0
  39. package/lib/commonjs/components/menu/constants.js +21 -0
  40. package/lib/commonjs/components/menu/constants.js.map +1 -0
  41. package/lib/commonjs/components/menu/index.js +16 -0
  42. package/lib/commonjs/components/menu/index.js.map +1 -0
  43. package/lib/commonjs/components/menu/styles.js +77 -0
  44. package/lib/commonjs/components/menu/styles.js.map +1 -0
  45. package/lib/commonjs/components/menu/types.d.js +2 -0
  46. package/lib/commonjs/components/menu/types.d.js.map +1 -0
  47. package/lib/commonjs/components/provider/Provider.js +98 -0
  48. package/lib/commonjs/components/provider/Provider.js.map +1 -0
  49. package/lib/commonjs/components/provider/index.js +16 -0
  50. package/lib/commonjs/components/provider/index.js.map +1 -0
  51. package/lib/commonjs/components/provider/reducer.js +50 -0
  52. package/lib/commonjs/components/provider/reducer.js.map +1 -0
  53. package/lib/commonjs/components/provider/types.d.js +2 -0
  54. package/lib/commonjs/components/provider/types.d.js.map +1 -0
  55. package/lib/commonjs/constants.js +60 -0
  56. package/lib/commonjs/constants.js.map +1 -0
  57. package/lib/commonjs/context/index.js +14 -0
  58. package/lib/commonjs/context/index.js.map +1 -0
  59. package/lib/commonjs/context/internal.js +13 -0
  60. package/lib/commonjs/context/internal.js.map +1 -0
  61. package/lib/commonjs/hooks/index.js +24 -0
  62. package/lib/commonjs/hooks/index.js.map +1 -0
  63. package/lib/commonjs/hooks/useDeviceOrientation.js +38 -0
  64. package/lib/commonjs/hooks/useDeviceOrientation.js.map +1 -0
  65. package/lib/commonjs/hooks/useInternal.js +15 -0
  66. package/lib/commonjs/hooks/useInternal.js.map +1 -0
  67. package/lib/commonjs/index.js +40 -0
  68. package/lib/commonjs/index.js.map +1 -0
  69. package/lib/commonjs/styleGuide.js +39 -0
  70. package/lib/commonjs/styleGuide.js.map +1 -0
  71. package/lib/commonjs/utils/calculations.js +73 -0
  72. package/lib/commonjs/utils/calculations.js.map +1 -0
  73. package/lib/commonjs/utils/validations.js +43 -0
  74. package/lib/commonjs/utils/validations.js.map +1 -0
  75. package/lib/module/components/backdrop/Backdrop.js +83 -0
  76. package/lib/module/components/backdrop/Backdrop.js.map +1 -0
  77. package/lib/module/components/backdrop/constants.js +4 -0
  78. package/lib/module/components/backdrop/constants.js.map +1 -0
  79. package/lib/module/components/backdrop/index.js +2 -0
  80. package/lib/module/components/backdrop/index.js.map +1 -0
  81. package/lib/module/components/backdrop/styles.js +7 -0
  82. package/lib/module/components/backdrop/styles.js.map +1 -0
  83. package/lib/module/components/flatList/FlatList.js +17 -0
  84. package/lib/module/components/flatList/FlatList.js.map +1 -0
  85. package/lib/module/components/flatList/index.js +2 -0
  86. package/lib/module/components/flatList/index.js.map +1 -0
  87. package/lib/module/components/holdItem/HoldItem.js +344 -0
  88. package/lib/module/components/holdItem/HoldItem.js.map +1 -0
  89. package/lib/module/components/holdItem/index.js +2 -0
  90. package/lib/module/components/holdItem/index.js.map +1 -0
  91. package/lib/module/components/holdItem/styles.js +12 -0
  92. package/lib/module/components/holdItem/styles.js.map +1 -0
  93. package/lib/module/components/holdItem/types.d.js +2 -0
  94. package/lib/module/components/holdItem/types.d.js.map +1 -0
  95. package/lib/module/components/icon/Icon.js +26 -0
  96. package/lib/module/components/icon/Icon.js.map +1 -0
  97. package/lib/module/components/icon/index.js +2 -0
  98. package/lib/module/components/icon/index.js.map +1 -0
  99. package/lib/module/components/menu/Menu.js +37 -0
  100. package/lib/module/components/menu/Menu.js.map +1 -0
  101. package/lib/module/components/menu/MenuItem.js +59 -0
  102. package/lib/module/components/menu/MenuItem.js.map +1 -0
  103. package/lib/module/components/menu/MenuItems.js +19 -0
  104. package/lib/module/components/menu/MenuItems.js.map +1 -0
  105. package/lib/module/components/menu/MenuList.js +93 -0
  106. package/lib/module/components/menu/MenuList.js.map +1 -0
  107. package/lib/module/components/menu/Separator.js +29 -0
  108. package/lib/module/components/menu/Separator.js.map +1 -0
  109. package/lib/module/components/menu/calculations.js +17 -0
  110. package/lib/module/components/menu/calculations.js.map +1 -0
  111. package/lib/module/components/menu/constants.js +8 -0
  112. package/lib/module/components/menu/constants.js.map +1 -0
  113. package/lib/module/components/menu/index.js +2 -0
  114. package/lib/module/components/menu/index.js.map +1 -0
  115. package/lib/module/components/menu/styles.js +63 -0
  116. package/lib/module/components/menu/styles.js.map +1 -0
  117. package/lib/module/components/menu/types.d.js +2 -0
  118. package/lib/module/components/menu/types.d.js.map +1 -0
  119. package/lib/module/components/provider/Provider.js +75 -0
  120. package/lib/module/components/provider/Provider.js.map +1 -0
  121. package/lib/module/components/provider/index.js +2 -0
  122. package/lib/module/components/provider/index.js.map +1 -0
  123. package/lib/module/components/provider/reducer.js +38 -0
  124. package/lib/module/components/provider/reducer.js.map +1 -0
  125. package/lib/module/components/provider/types.d.js +2 -0
  126. package/lib/module/components/provider/types.d.js.map +1 -0
  127. package/lib/module/constants.js +37 -0
  128. package/lib/module/constants.js.map +1 -0
  129. package/lib/module/context/index.js +2 -0
  130. package/lib/module/context/index.js.map +1 -0
  131. package/lib/module/context/internal.js +4 -0
  132. package/lib/module/context/internal.js.map +1 -0
  133. package/lib/module/hooks/index.js +3 -0
  134. package/lib/module/hooks/index.js.map +1 -0
  135. package/lib/module/hooks/useDeviceOrientation.js +27 -0
  136. package/lib/module/hooks/useDeviceOrientation.js.map +1 -0
  137. package/lib/module/hooks/useInternal.js +4 -0
  138. package/lib/module/hooks/useInternal.js.map +1 -0
  139. package/lib/module/index.js +5 -0
  140. package/lib/module/index.js.map +1 -0
  141. package/lib/module/styleGuide.js +30 -0
  142. package/lib/module/styleGuide.js.map +1 -0
  143. package/lib/module/utils/calculations.js +51 -0
  144. package/lib/module/utils/calculations.js.map +1 -0
  145. package/lib/module/utils/validations.js +38 -0
  146. package/lib/module/utils/validations.js.map +1 -0
  147. package/lib/typescript/components/backdrop/Backdrop.d.ts +3 -0
  148. package/lib/typescript/components/backdrop/constants.d.ts +2 -0
  149. package/lib/typescript/components/backdrop/index.d.ts +1 -0
  150. package/lib/typescript/components/backdrop/styles.d.ts +10 -0
  151. package/lib/typescript/components/flatList/FlatList.d.ts +5 -0
  152. package/lib/typescript/components/flatList/index.d.ts +2 -0
  153. package/lib/typescript/components/holdItem/HoldItem.d.ts +4 -0
  154. package/lib/typescript/components/holdItem/index.d.ts +2 -0
  155. package/lib/typescript/components/holdItem/styles.d.ts +15 -0
  156. package/lib/typescript/components/holdItem/types.d.ts +131 -0
  157. package/lib/typescript/components/icon/Icon.d.ts +7 -0
  158. package/lib/typescript/components/icon/index.d.ts +1 -0
  159. package/lib/typescript/components/menu/Menu.d.ts +3 -0
  160. package/lib/typescript/components/menu/MenuItem.d.ts +8 -0
  161. package/lib/typescript/components/menu/MenuItems.d.ts +6 -0
  162. package/lib/typescript/components/menu/MenuList.d.ts +3 -0
  163. package/lib/typescript/components/menu/Separator.d.ts +3 -0
  164. package/lib/typescript/components/menu/calculations.d.ts +4 -0
  165. package/lib/typescript/components/menu/constants.d.ts +7 -0
  166. package/lib/typescript/components/menu/index.d.ts +1 -0
  167. package/lib/typescript/components/menu/styles.d.ts +59 -0
  168. package/lib/typescript/components/menu/types.d.ts +28 -0
  169. package/lib/typescript/components/provider/Provider.d.ts +10 -0
  170. package/lib/typescript/components/provider/index.d.ts +2 -0
  171. package/lib/typescript/components/provider/reducer.d.ts +20 -0
  172. package/lib/typescript/components/provider/types.d.ts +33 -0
  173. package/lib/typescript/constants.d.ts +29 -0
  174. package/lib/typescript/context/index.d.ts +1 -0
  175. package/lib/typescript/context/internal.d.ts +16 -0
  176. package/lib/typescript/hooks/index.d.ts +2 -0
  177. package/lib/typescript/hooks/useDeviceOrientation.d.ts +3 -0
  178. package/lib/typescript/hooks/useInternal.d.ts +1 -0
  179. package/lib/typescript/index.d.ts +4 -0
  180. package/lib/typescript/styleGuide.d.ts +28 -0
  181. package/lib/typescript/utils/calculations.d.ts +14 -0
  182. package/lib/typescript/utils/validations.d.ts +3 -0
  183. package/package.json +106 -0
  184. package/src/components/backdrop/Backdrop.tsx +138 -0
  185. package/src/components/backdrop/constants.ts +8 -0
  186. package/src/components/backdrop/index.ts +1 -0
  187. package/src/components/backdrop/styles.ts +8 -0
  188. package/src/components/flatList/FlatList.tsx +23 -0
  189. package/src/components/flatList/index.ts +2 -0
  190. package/src/components/holdItem/HoldItem.tsx +449 -0
  191. package/src/components/holdItem/index.ts +2 -0
  192. package/src/components/holdItem/styles.ts +11 -0
  193. package/src/components/holdItem/types.d.ts +131 -0
  194. package/src/components/icon/Icon.tsx +33 -0
  195. package/src/components/icon/index.ts +1 -0
  196. package/src/components/menu/Menu.tsx +57 -0
  197. package/src/components/menu/MenuItem.tsx +79 -0
  198. package/src/components/menu/MenuItems.tsx +26 -0
  199. package/src/components/menu/MenuList.tsx +151 -0
  200. package/src/components/menu/Separator.tsx +28 -0
  201. package/src/components/menu/calculations.ts +49 -0
  202. package/src/components/menu/constants.ts +9 -0
  203. package/src/components/menu/index.ts +1 -0
  204. package/src/components/menu/styles.ts +64 -0
  205. package/src/components/menu/types.d.ts +28 -0
  206. package/src/components/provider/Provider.tsx +105 -0
  207. package/src/components/provider/index.ts +2 -0
  208. package/src/components/provider/reducer.ts +48 -0
  209. package/src/components/provider/types.d.ts +33 -0
  210. package/src/constants.ts +54 -0
  211. package/src/context/index.ts +1 -0
  212. package/src/context/internal.ts +19 -0
  213. package/src/hooks/index.ts +2 -0
  214. package/src/hooks/useDeviceOrientation.ts +28 -0
  215. package/src/hooks/useInternal.ts +4 -0
  216. package/src/index.ts +4 -0
  217. package/src/styleGuide.ts +31 -0
  218. package/src/utils/calculations.ts +110 -0
  219. package/src/utils/validations.ts +42 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["styles.ts"],"names":["StyleSheet","styles","create","container","absoluteFillObject","zIndex"],"mappings":"AAAA,SAASA,UAAT,QAA2B,cAA3B;AAEA,OAAO,MAAMC,MAAM,GAAGD,UAAU,CAACE,MAAX,CAAkB;AACtCC,EAAAA,SAAS,EAAE,EACT,GAAGH,UAAU,CAACI,kBADL;AAETC,IAAAA,MAAM,EAAE;AAFC;AAD2B,CAAlB,CAAf","sourcesContent":["import { StyleSheet } from 'react-native';\n\nexport const styles = StyleSheet.create({\n container: {\n ...StyleSheet.absoluteFillObject,\n zIndex: 0,\n },\n});\n"]}
@@ -0,0 +1,17 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React, { memo } from 'react';
4
+ import { FlatList as RNFlatList } from 'react-native';
5
+ import isEqual from 'lodash.isequal';
6
+ import Animated from 'react-native-reanimated';
7
+ const AnimatedFlatList = Animated.createAnimatedComponent(RNFlatList);
8
+
9
+ const HoldMenuFlatListComponent = props => {
10
+ return /*#__PURE__*/React.createElement(AnimatedFlatList, _extends({}, props, {
11
+ scrollEventThrottle: 16
12
+ }));
13
+ };
14
+
15
+ const HoldMenuFlatList = /*#__PURE__*/memo(HoldMenuFlatListComponent, isEqual);
16
+ export default HoldMenuFlatList;
17
+ //# sourceMappingURL=FlatList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["FlatList.tsx"],"names":["React","memo","FlatList","RNFlatList","isEqual","Animated","AnimatedFlatList","createAnimatedComponent","HoldMenuFlatListComponent","props","HoldMenuFlatList"],"mappings":";;AAAA,OAAOA,KAAP,IAAgBC,IAAhB,QAA4B,OAA5B;AACA,SACEC,QAAQ,IAAIC,UADd,QAGO,cAHP;AAKA,OAAOC,OAAP,MAAoB,gBAApB;AACA,OAAOC,QAAP,MAAqB,yBAArB;AAEA,MAAMC,gBAAgB,GAAGD,QAAQ,CAACE,uBAAT,CAAiCJ,UAAjC,CAAzB;;AAOA,MAAMK,yBAAyB,GAAIC,KAAD,IAAuC;AACvE,sBAAO,oBAAC,gBAAD,eAAsBA,KAAtB;AAA6B,IAAA,mBAAmB,EAAE;AAAlD,KAAP;AACD,CAFD;;AAIA,MAAMC,gBAAgB,gBAAGT,IAAI,CAACO,yBAAD,EAA4BJ,OAA5B,CAA7B;AAEA,eAAeM,gBAAf","sourcesContent":["import React, { memo } from 'react';\nimport {\n FlatList as RNFlatList,\n FlatListProps as RNFlatListProps,\n} from 'react-native';\n\nimport isEqual from 'lodash.isequal';\nimport Animated from 'react-native-reanimated';\n\nconst AnimatedFlatList = Animated.createAnimatedComponent(RNFlatList);\n\nexport type HoldMenuFlatListProps<T> = Omit<\n RNFlatListProps<T>,\n 'scrollEventThrottle'\n>;\n\nconst HoldMenuFlatListComponent = (props: HoldMenuFlatListProps<any>) => {\n return <AnimatedFlatList {...props} scrollEventThrottle={16} />;\n};\n\nconst HoldMenuFlatList = memo(HoldMenuFlatListComponent, isEqual);\n\nexport default HoldMenuFlatList;\n"]}
@@ -0,0 +1,2 @@
1
+ export { default } from './FlatList';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.ts"],"names":["default"],"mappings":"AAAA,SAASA,OAAT,QAAwB,YAAxB","sourcesContent":["export { default } from './FlatList';\nexport type { HoldMenuFlatListProps } from './FlatList';\n"]}
@@ -0,0 +1,344 @@
1
+ import React, { memo, useMemo } from 'react';
2
+ //#region reanimated & gesture handler
3
+ import { TapGestureHandler, LongPressGestureHandler } from 'react-native-gesture-handler';
4
+ import Animated, { measure, runOnJS, useAnimatedGestureHandler, useAnimatedProps, useAnimatedRef, useAnimatedStyle, useSharedValue, withDelay, withTiming, withSequence, withSpring, useAnimatedReaction } from 'react-native-reanimated'; //#endregion
5
+ //#region dependencies
6
+
7
+ import { Portal } from '@gorhom/portal';
8
+ import { nanoid } from 'nanoid/non-secure'; // @ts-ignore
9
+
10
+ import * as Haptics from 'expo-haptics'; //#endregion
11
+ //#region utils & types
12
+
13
+ import { getTransformOrigin, calculateMenuHeight } from '../../utils/calculations';
14
+ import { HOLD_ITEM_TRANSFORM_DURATION, HOLD_ITEM_SCALE_DOWN_DURATION, HOLD_ITEM_SCALE_DOWN_VALUE, SPRING_CONFIGURATION, WINDOW_HEIGHT, WINDOW_WIDTH, CONTEXT_MENU_STATE } from '../../constants';
15
+ import { useDeviceOrientation } from '../../hooks';
16
+ import styles from './styles';
17
+ import styleGuide from '../../styleGuide';
18
+ import { useInternal } from '../../hooks'; //#endregion
19
+
20
+ const HoldItemComponent = ({
21
+ items,
22
+ bottom,
23
+ containerStyles,
24
+ disableMove,
25
+ menuAnchorPosition,
26
+ activateOn,
27
+ hapticFeedback,
28
+ actionParams,
29
+ closeOnTap,
30
+ longPressMinDurationMs = 150,
31
+ children
32
+ }) => {
33
+ //#region hooks
34
+ const {
35
+ state,
36
+ menuProps,
37
+ safeAreaInsets
38
+ } = useInternal();
39
+ const deviceOrientation = useDeviceOrientation(); //#endregion
40
+ //#region variables
41
+
42
+ const isActive = useSharedValue(false);
43
+ const isAnimationStarted = useSharedValue(false);
44
+ const itemRectY = useSharedValue(0);
45
+ const itemRectX = useSharedValue(0);
46
+ const itemRectWidth = useSharedValue(0);
47
+ const itemRectHeight = useSharedValue(0);
48
+ const itemScale = useSharedValue(1);
49
+ const transformValue = useSharedValue(0);
50
+ const transformOrigin = useSharedValue(menuAnchorPosition || 'top-right');
51
+ const key = useMemo(() => `hold-item-${nanoid()}`, []);
52
+ const menuHeight = useMemo(() => {
53
+ const itemsWithSeparator = items.filter(item => item.withSeparator);
54
+ return calculateMenuHeight(items.length, itemsWithSeparator.length);
55
+ }, [items]);
56
+ const isHold = !activateOn || activateOn === 'hold'; //#endregion
57
+ //#region refs
58
+
59
+ const containerRef = useAnimatedRef(); //#endregion
60
+ //#region functions
61
+
62
+ const hapticResponse = () => {
63
+ const style = !hapticFeedback ? 'Medium' : hapticFeedback;
64
+
65
+ switch (style) {
66
+ case `Selection`:
67
+ Haptics.selectionAsync();
68
+ break;
69
+
70
+ case `Light`:
71
+ case `Medium`:
72
+ case `Heavy`:
73
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle[style]);
74
+ break;
75
+
76
+ case `Success`:
77
+ case `Warning`:
78
+ case `Error`:
79
+ Haptics.notificationAsync(Haptics.NotificationFeedbackType[style]);
80
+ break;
81
+
82
+ default:
83
+ }
84
+ }; //#endregion
85
+ //#region worklet functions
86
+
87
+
88
+ const activateAnimation = ctx => {
89
+ 'worklet';
90
+
91
+ if (!ctx.didMeasureLayout) {
92
+ const measured = measure(containerRef);
93
+ itemRectY.value = measured.pageY;
94
+ itemRectX.value = measured.pageX;
95
+ itemRectHeight.value = measured.height;
96
+ itemRectWidth.value = measured.width;
97
+
98
+ if (!menuAnchorPosition) {
99
+ const position = getTransformOrigin(measured.pageX, itemRectWidth.value, deviceOrientation === 'portrait' ? WINDOW_WIDTH : WINDOW_HEIGHT, bottom);
100
+ transformOrigin.value = position;
101
+ }
102
+ }
103
+ };
104
+
105
+ const calculateTransformValue = () => {
106
+ 'worklet';
107
+
108
+ const height = deviceOrientation === 'portrait' ? WINDOW_HEIGHT : WINDOW_WIDTH;
109
+ const isAnchorPointTop = transformOrigin.value.includes('top');
110
+ let tY = 0;
111
+
112
+ if (!disableMove) {
113
+ if (isAnchorPointTop) {
114
+ const topTransform = itemRectY.value + itemRectHeight.value + menuHeight + styleGuide.spacing + ((safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.bottom) || 0);
115
+ tY = topTransform > height ? height - topTransform : 0;
116
+ } else {
117
+ const bottomTransform = itemRectY.value - menuHeight - ((safeAreaInsets === null || safeAreaInsets === void 0 ? void 0 : safeAreaInsets.top) || 0);
118
+ tY = bottomTransform < 0 ? -bottomTransform + styleGuide.spacing * 2 : 0;
119
+ }
120
+ }
121
+
122
+ return tY;
123
+ };
124
+
125
+ const setMenuProps = () => {
126
+ 'worklet';
127
+
128
+ menuProps.value = {
129
+ itemHeight: itemRectHeight.value,
130
+ itemWidth: itemRectWidth.value,
131
+ itemY: itemRectY.value,
132
+ itemX: itemRectX.value,
133
+ anchorPosition: transformOrigin.value,
134
+ menuHeight: menuHeight,
135
+ items,
136
+ transformValue: transformValue.value,
137
+ actionParams: actionParams || {}
138
+ };
139
+ };
140
+
141
+ const scaleBack = () => {
142
+ 'worklet';
143
+
144
+ itemScale.value = withTiming(1, {
145
+ duration: HOLD_ITEM_TRANSFORM_DURATION / 2
146
+ });
147
+ };
148
+
149
+ const onCompletion = isFinised => {
150
+ 'worklet';
151
+
152
+ const isListValid = items && items.length > 0;
153
+
154
+ if (isFinised && isListValid) {
155
+ state.value = CONTEXT_MENU_STATE.ACTIVE;
156
+ isActive.value = true;
157
+ scaleBack();
158
+
159
+ if (hapticFeedback !== 'None') {
160
+ runOnJS(hapticResponse)();
161
+ }
162
+ }
163
+
164
+ isAnimationStarted.value = false; // TODO: Warn user if item list is empty or not given
165
+ };
166
+
167
+ const scaleHold = () => {
168
+ 'worklet';
169
+
170
+ itemScale.value = withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {
171
+ duration: HOLD_ITEM_SCALE_DOWN_DURATION
172
+ }, onCompletion);
173
+ };
174
+
175
+ const scaleTap = () => {
176
+ 'worklet';
177
+
178
+ isAnimationStarted.value = true;
179
+ itemScale.value = withSequence(withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {
180
+ duration: HOLD_ITEM_SCALE_DOWN_DURATION
181
+ }), withTiming(1, {
182
+ duration: HOLD_ITEM_TRANSFORM_DURATION / 2
183
+ }, onCompletion));
184
+ };
185
+ /**
186
+ * When use tap activation ("tap") and trying to tap multiple times,
187
+ * scale animation is called again despite it is started. This causes a bug.
188
+ * To prevent this, it is better to check is animation already started.
189
+ */
190
+
191
+
192
+ const canCallActivateFunctions = () => {
193
+ 'worklet';
194
+
195
+ const willActivateWithTap = activateOn === 'double-tap' || activateOn === 'tap';
196
+ return willActivateWithTap && !isAnimationStarted.value || !willActivateWithTap;
197
+ }; //#endregion
198
+ //#region gesture events
199
+
200
+
201
+ const gestureEvent = useAnimatedGestureHandler({
202
+ onActive: (_, context) => {
203
+ if (canCallActivateFunctions()) {
204
+ if (!context.didMeasureLayout) {
205
+ activateAnimation(context);
206
+ transformValue.value = calculateTransformValue();
207
+ setMenuProps();
208
+ context.didMeasureLayout = true;
209
+ }
210
+
211
+ if (!isActive.value) {
212
+ if (isHold) {
213
+ scaleHold();
214
+ } else {
215
+ scaleTap();
216
+ }
217
+ }
218
+ }
219
+ },
220
+ onFinish: (_, context) => {
221
+ context.didMeasureLayout = false;
222
+
223
+ if (isHold) {
224
+ scaleBack();
225
+ }
226
+ }
227
+ });
228
+ const overlayGestureEvent = useAnimatedGestureHandler({
229
+ onActive: _ => {
230
+ if (closeOnTap) state.value = CONTEXT_MENU_STATE.END;
231
+ }
232
+ }); //#endregion
233
+ //#region animated styles & props
234
+
235
+ const animatedContainerStyle = useAnimatedStyle(() => {
236
+ const animateOpacity = () => withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(1, {
237
+ duration: 0
238
+ }));
239
+
240
+ return {
241
+ opacity: isActive.value ? 0 : animateOpacity(),
242
+ transform: [{
243
+ scale: isActive.value ? withTiming(1, {
244
+ duration: HOLD_ITEM_TRANSFORM_DURATION
245
+ }) : itemScale.value
246
+ }]
247
+ };
248
+ });
249
+ const containerStyle = React.useMemo(() => [containerStyles, animatedContainerStyle], [containerStyles, animatedContainerStyle]);
250
+ const animatedPortalStyle = useAnimatedStyle(() => {
251
+ const animateOpacity = () => withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(0, {
252
+ duration: 0
253
+ }));
254
+
255
+ let tY = calculateTransformValue();
256
+
257
+ const transformAnimation = () => disableMove ? 0 : isActive.value ? withSpring(tY, SPRING_CONFIGURATION) : withTiming(-0.1, {
258
+ duration: HOLD_ITEM_TRANSFORM_DURATION
259
+ });
260
+
261
+ return {
262
+ zIndex: 10,
263
+ position: 'absolute',
264
+ top: itemRectY.value,
265
+ left: itemRectX.value,
266
+ width: itemRectWidth.value,
267
+ height: itemRectHeight.value,
268
+ opacity: isActive.value ? 1 : animateOpacity(),
269
+ transform: [{
270
+ translateY: transformAnimation()
271
+ }, {
272
+ scale: isActive.value ? withTiming(1, {
273
+ duration: HOLD_ITEM_TRANSFORM_DURATION
274
+ }) : itemScale.value
275
+ }]
276
+ };
277
+ });
278
+ const portalContainerStyle = useMemo(() => [styles.holdItem, animatedPortalStyle], [animatedPortalStyle]);
279
+ const animatedPortalProps = useAnimatedProps(() => ({
280
+ pointerEvents: isActive.value ? 'auto' : 'none'
281
+ })); //#endregion
282
+ //#region animated effects
283
+
284
+ useAnimatedReaction(() => state.value, _state => {
285
+ if (_state === CONTEXT_MENU_STATE.END) {
286
+ isActive.value = false;
287
+ }
288
+ }); //#endregion
289
+ //#region components
290
+
291
+ const GestureHandler = useMemo(() => {
292
+ switch (activateOn) {
293
+ case `double-tap`:
294
+ return ({
295
+ children: handlerChildren
296
+ }) => /*#__PURE__*/React.createElement(TapGestureHandler, {
297
+ numberOfTaps: 2,
298
+ onHandlerStateChange: gestureEvent
299
+ }, handlerChildren);
300
+
301
+ case `tap`:
302
+ return ({
303
+ children: handlerChildren
304
+ }) => /*#__PURE__*/React.createElement(TapGestureHandler, {
305
+ numberOfTaps: 1,
306
+ onHandlerStateChange: gestureEvent
307
+ }, handlerChildren);
308
+ // default is hold
309
+
310
+ default:
311
+ return ({
312
+ children: handlerChildren
313
+ }) => /*#__PURE__*/React.createElement(LongPressGestureHandler, {
314
+ minDurationMs: longPressMinDurationMs,
315
+ onHandlerStateChange: gestureEvent
316
+ }, handlerChildren);
317
+ }
318
+ }, [activateOn, gestureEvent]);
319
+ const PortalOverlay = useMemo(() => {
320
+ return () => /*#__PURE__*/React.createElement(TapGestureHandler, {
321
+ numberOfTaps: 1,
322
+ onHandlerStateChange: overlayGestureEvent
323
+ }, /*#__PURE__*/React.createElement(Animated.View, {
324
+ style: styles.portalOverlay
325
+ }));
326
+ }, [overlayGestureEvent]); //#endregion
327
+ //#region render
328
+
329
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(GestureHandler, null, /*#__PURE__*/React.createElement(Animated.View, {
330
+ ref: containerRef,
331
+ style: containerStyle
332
+ }, children)), /*#__PURE__*/React.createElement(Portal, {
333
+ key: key,
334
+ name: key
335
+ }, /*#__PURE__*/React.createElement(Animated.View, {
336
+ key: key,
337
+ style: portalContainerStyle,
338
+ animatedProps: animatedPortalProps
339
+ }, /*#__PURE__*/React.createElement(PortalOverlay, null), children))); //#endregion
340
+ };
341
+
342
+ const HoldItem = /*#__PURE__*/memo(HoldItemComponent);
343
+ export default HoldItem;
344
+ //# sourceMappingURL=HoldItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["HoldItem.tsx"],"names":["React","memo","useMemo","TapGestureHandler","LongPressGestureHandler","Animated","measure","runOnJS","useAnimatedGestureHandler","useAnimatedProps","useAnimatedRef","useAnimatedStyle","useSharedValue","withDelay","withTiming","withSequence","withSpring","useAnimatedReaction","Portal","nanoid","Haptics","getTransformOrigin","calculateMenuHeight","HOLD_ITEM_TRANSFORM_DURATION","HOLD_ITEM_SCALE_DOWN_DURATION","HOLD_ITEM_SCALE_DOWN_VALUE","SPRING_CONFIGURATION","WINDOW_HEIGHT","WINDOW_WIDTH","CONTEXT_MENU_STATE","useDeviceOrientation","styles","styleGuide","useInternal","HoldItemComponent","items","bottom","containerStyles","disableMove","menuAnchorPosition","activateOn","hapticFeedback","actionParams","closeOnTap","longPressMinDurationMs","children","state","menuProps","safeAreaInsets","deviceOrientation","isActive","isAnimationStarted","itemRectY","itemRectX","itemRectWidth","itemRectHeight","itemScale","transformValue","transformOrigin","key","menuHeight","itemsWithSeparator","filter","item","withSeparator","length","isHold","containerRef","hapticResponse","style","selectionAsync","impactAsync","ImpactFeedbackStyle","notificationAsync","NotificationFeedbackType","activateAnimation","ctx","didMeasureLayout","measured","value","pageY","pageX","height","width","position","calculateTransformValue","isAnchorPointTop","includes","tY","topTransform","spacing","bottomTransform","top","setMenuProps","itemHeight","itemWidth","itemY","itemX","anchorPosition","scaleBack","duration","onCompletion","isFinised","isListValid","ACTIVE","scaleHold","scaleTap","canCallActivateFunctions","willActivateWithTap","gestureEvent","onActive","_","context","onFinish","overlayGestureEvent","END","animatedContainerStyle","animateOpacity","opacity","transform","scale","containerStyle","animatedPortalStyle","transformAnimation","zIndex","left","translateY","portalContainerStyle","holdItem","animatedPortalProps","pointerEvents","_state","GestureHandler","handlerChildren","PortalOverlay","portalOverlay","HoldItem"],"mappings":"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","sourcesContent":["import React, { memo, useMemo } from 'react';\nimport { ViewProps } from 'react-native';\n\n//#region reanimated & gesture handler\nimport {\n TapGestureHandler,\n LongPressGestureHandler,\n TapGestureHandlerGestureEvent,\n LongPressGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n measure,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedProps,\n useAnimatedRef,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withTiming,\n withSequence,\n withSpring,\n useAnimatedReaction,\n} from 'react-native-reanimated';\n//#endregion\n\n//#region dependencies\nimport { Portal } from '@gorhom/portal';\nimport { nanoid } from 'nanoid/non-secure';\n// @ts-ignore\nimport * as Haptics from 'expo-haptics';\n//#endregion\n\n//#region utils & types\nimport {\n TransformOriginAnchorPosition,\n getTransformOrigin,\n calculateMenuHeight,\n} from '../../utils/calculations';\nimport {\n HOLD_ITEM_TRANSFORM_DURATION,\n HOLD_ITEM_SCALE_DOWN_DURATION,\n HOLD_ITEM_SCALE_DOWN_VALUE,\n SPRING_CONFIGURATION,\n WINDOW_HEIGHT,\n WINDOW_WIDTH,\n CONTEXT_MENU_STATE,\n} from '../../constants';\nimport { useDeviceOrientation } from '../../hooks';\nimport styles from './styles';\n\nimport type { HoldItemProps, GestureHandlerProps } from './types';\nimport styleGuide from '../../styleGuide';\nimport { useInternal } from '../../hooks';\n//#endregion\n\ntype Context = { didMeasureLayout: boolean };\n\nconst HoldItemComponent = ({\n items,\n bottom,\n containerStyles,\n disableMove,\n menuAnchorPosition,\n activateOn,\n hapticFeedback,\n actionParams,\n closeOnTap,\n longPressMinDurationMs = 150,\n children,\n}: HoldItemProps) => {\n //#region hooks\n const { state, menuProps, safeAreaInsets } = useInternal();\n const deviceOrientation = useDeviceOrientation();\n //#endregion\n\n //#region variables\n const isActive = useSharedValue(false);\n const isAnimationStarted = useSharedValue(false);\n\n const itemRectY = useSharedValue<number>(0);\n const itemRectX = useSharedValue<number>(0);\n const itemRectWidth = useSharedValue<number>(0);\n const itemRectHeight = useSharedValue<number>(0);\n const itemScale = useSharedValue<number>(1);\n const transformValue = useSharedValue<number>(0);\n\n const transformOrigin = useSharedValue<TransformOriginAnchorPosition>(\n menuAnchorPosition || 'top-right'\n );\n\n const key = useMemo(() => `hold-item-${nanoid()}`, []);\n const menuHeight = useMemo(() => {\n const itemsWithSeparator = items.filter(item => item.withSeparator);\n return calculateMenuHeight(items.length, itemsWithSeparator.length);\n }, [items]);\n\n const isHold = !activateOn || activateOn === 'hold';\n //#endregion\n\n //#region refs\n const containerRef = useAnimatedRef<Animated.View>();\n //#endregion\n\n //#region functions\n const hapticResponse = () => {\n const style = !hapticFeedback ? 'Medium' : hapticFeedback;\n switch (style) {\n case `Selection`:\n Haptics.selectionAsync();\n break;\n case `Light`:\n case `Medium`:\n case `Heavy`:\n Haptics.impactAsync(Haptics.ImpactFeedbackStyle[style]);\n break;\n case `Success`:\n case `Warning`:\n case `Error`:\n Haptics.notificationAsync(Haptics.NotificationFeedbackType[style]);\n break;\n default:\n }\n };\n //#endregion\n\n //#region worklet functions\n const activateAnimation = (ctx: any) => {\n 'worklet';\n if (!ctx.didMeasureLayout) {\n const measured = measure(containerRef);\n\n itemRectY.value = measured.pageY;\n itemRectX.value = measured.pageX;\n itemRectHeight.value = measured.height;\n itemRectWidth.value = measured.width;\n\n if (!menuAnchorPosition) {\n const position = getTransformOrigin(\n measured.pageX,\n itemRectWidth.value,\n deviceOrientation === 'portrait' ? WINDOW_WIDTH : WINDOW_HEIGHT,\n bottom\n );\n transformOrigin.value = position;\n }\n }\n };\n\n const calculateTransformValue = () => {\n 'worklet';\n\n const height =\n deviceOrientation === 'portrait' ? WINDOW_HEIGHT : WINDOW_WIDTH;\n\n const isAnchorPointTop = transformOrigin.value.includes('top');\n\n let tY = 0;\n if (!disableMove) {\n if (isAnchorPointTop) {\n const topTransform =\n itemRectY.value +\n itemRectHeight.value +\n menuHeight +\n styleGuide.spacing +\n (safeAreaInsets?.bottom || 0);\n\n tY = topTransform > height ? height - topTransform : 0;\n } else {\n const bottomTransform =\n itemRectY.value - menuHeight - (safeAreaInsets?.top || 0);\n tY =\n bottomTransform < 0 ? -bottomTransform + styleGuide.spacing * 2 : 0;\n }\n }\n return tY;\n };\n\n const setMenuProps = () => {\n 'worklet';\n\n menuProps.value = {\n itemHeight: itemRectHeight.value,\n itemWidth: itemRectWidth.value,\n itemY: itemRectY.value,\n itemX: itemRectX.value,\n anchorPosition: transformOrigin.value,\n menuHeight: menuHeight,\n items,\n transformValue: transformValue.value,\n actionParams: actionParams || {},\n };\n };\n\n const scaleBack = () => {\n 'worklet';\n itemScale.value = withTiming(1, {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n });\n };\n\n const onCompletion = (isFinised?: boolean) => {\n 'worklet';\n const isListValid = items && items.length > 0;\n if (isFinised && isListValid) {\n state.value = CONTEXT_MENU_STATE.ACTIVE;\n isActive.value = true;\n scaleBack();\n if (hapticFeedback !== 'None') {\n runOnJS(hapticResponse)();\n }\n }\n\n isAnimationStarted.value = false;\n\n // TODO: Warn user if item list is empty or not given\n };\n\n const scaleHold = () => {\n 'worklet';\n itemScale.value = withTiming(\n HOLD_ITEM_SCALE_DOWN_VALUE,\n { duration: HOLD_ITEM_SCALE_DOWN_DURATION },\n onCompletion\n );\n };\n\n const scaleTap = () => {\n 'worklet';\n isAnimationStarted.value = true;\n\n itemScale.value = withSequence(\n withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {\n duration: HOLD_ITEM_SCALE_DOWN_DURATION,\n }),\n withTiming(\n 1,\n {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n },\n onCompletion\n )\n );\n };\n\n /**\n * When use tap activation (\"tap\") and trying to tap multiple times,\n * scale animation is called again despite it is started. This causes a bug.\n * To prevent this, it is better to check is animation already started.\n */\n const canCallActivateFunctions = () => {\n 'worklet';\n const willActivateWithTap =\n activateOn === 'double-tap' || activateOn === 'tap';\n\n return (\n (willActivateWithTap && !isAnimationStarted.value) || !willActivateWithTap\n );\n };\n //#endregion\n\n //#region gesture events\n const gestureEvent = useAnimatedGestureHandler<\n LongPressGestureHandlerGestureEvent | TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: (_, context) => {\n if (canCallActivateFunctions()) {\n if (!context.didMeasureLayout) {\n activateAnimation(context);\n transformValue.value = calculateTransformValue();\n setMenuProps();\n context.didMeasureLayout = true;\n }\n\n if (!isActive.value) {\n if (isHold) {\n scaleHold();\n } else {\n scaleTap();\n }\n }\n }\n },\n onFinish: (_, context) => {\n context.didMeasureLayout = false;\n if (isHold) {\n scaleBack();\n }\n },\n });\n\n const overlayGestureEvent = useAnimatedGestureHandler<\n TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: _ => {\n if (closeOnTap) state.value = CONTEXT_MENU_STATE.END;\n },\n });\n //#endregion\n\n //#region animated styles & props\n const animatedContainerStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(1, { duration: 0 }));\n\n return {\n opacity: isActive.value ? 0 : animateOpacity(),\n transform: [\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const containerStyle = React.useMemo(\n () => [containerStyles, animatedContainerStyle],\n [containerStyles, animatedContainerStyle]\n );\n\n const animatedPortalStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(0, { duration: 0 }));\n\n let tY = calculateTransformValue();\n const transformAnimation = () =>\n disableMove\n ? 0\n : isActive.value\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(-0.1, { duration: HOLD_ITEM_TRANSFORM_DURATION });\n\n return {\n zIndex: 10,\n position: 'absolute',\n top: itemRectY.value,\n left: itemRectX.value,\n width: itemRectWidth.value,\n height: itemRectHeight.value,\n opacity: isActive.value ? 1 : animateOpacity(),\n transform: [\n {\n translateY: transformAnimation(),\n },\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const portalContainerStyle = useMemo(\n () => [styles.holdItem, animatedPortalStyle],\n [animatedPortalStyle]\n );\n\n const animatedPortalProps = useAnimatedProps<ViewProps>(() => ({\n pointerEvents: isActive.value ? 'auto' : 'none',\n }));\n //#endregion\n\n //#region animated effects\n useAnimatedReaction(\n () => state.value,\n _state => {\n if (_state === CONTEXT_MENU_STATE.END) {\n isActive.value = false;\n }\n }\n );\n //#endregion\n\n //#region components\n const GestureHandler = useMemo(() => {\n switch (activateOn) {\n case `double-tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={2}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n case `tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n // default is hold\n default:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <LongPressGestureHandler\n minDurationMs={longPressMinDurationMs}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </LongPressGestureHandler>\n );\n }\n }, [activateOn, gestureEvent]);\n\n const PortalOverlay = useMemo(() => {\n return () => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={overlayGestureEvent}\n >\n <Animated.View style={styles.portalOverlay} />\n </TapGestureHandler>\n );\n }, [overlayGestureEvent]);\n //#endregion\n\n //#region render\n return (\n <>\n <GestureHandler>\n <Animated.View ref={containerRef} style={containerStyle}>\n {children}\n </Animated.View>\n </GestureHandler>\n\n <Portal key={key} name={key}>\n <Animated.View\n key={key}\n style={portalContainerStyle}\n animatedProps={animatedPortalProps}\n >\n <PortalOverlay />\n {children}\n </Animated.View>\n </Portal>\n </>\n );\n //#endregion\n};\n\nconst HoldItem = memo(HoldItemComponent);\n\nexport default HoldItem;\n"]}
@@ -0,0 +1,2 @@
1
+ export { default } from './HoldItem';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.ts"],"names":["default"],"mappings":"AAAA,SAASA,OAAT,QAAwB,YAAxB","sourcesContent":["export { default } from './HoldItem';\nexport type { HoldItemProps } from './types';\n"]}
@@ -0,0 +1,12 @@
1
+ import { StyleSheet } from 'react-native';
2
+ const styles = StyleSheet.create({
3
+ holdItem: {
4
+ zIndex: 10,
5
+ position: 'absolute'
6
+ },
7
+ portalOverlay: { ...StyleSheet.absoluteFillObject,
8
+ zIndex: 15
9
+ }
10
+ });
11
+ export default styles;
12
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["styles.ts"],"names":["StyleSheet","styles","create","holdItem","zIndex","position","portalOverlay","absoluteFillObject"],"mappings":"AAAA,SAASA,UAAT,QAA2B,cAA3B;AAEA,MAAMC,MAAM,GAAGD,UAAU,CAACE,MAAX,CAAkB;AAC/BC,EAAAA,QAAQ,EAAE;AAAEC,IAAAA,MAAM,EAAE,EAAV;AAAcC,IAAAA,QAAQ,EAAE;AAAxB,GADqB;AAE/BC,EAAAA,aAAa,EAAE,EACb,GAAGN,UAAU,CAACO,kBADD;AAEbH,IAAAA,MAAM,EAAE;AAFK;AAFgB,CAAlB,CAAf;AAQA,eAAeH,MAAf","sourcesContent":["import { StyleSheet } from 'react-native';\n\nconst styles = StyleSheet.create({\n holdItem: { zIndex: 10, position: 'absolute' },\n portalOverlay: {\n ...StyleSheet.absoluteFillObject,\n zIndex: 15,\n },\n});\n\nexport default styles;\n"]}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","sourcesContent":[]}
@@ -0,0 +1,26 @@
1
+ import React, { memo } from 'react';
2
+ import Animated, { useAnimatedProps } from 'react-native-reanimated';
3
+ import { useInternal } from '../../hooks';
4
+
5
+ const Icon = ({
6
+ iconComponent,
7
+ name
8
+ }) => {
9
+ const {
10
+ theme
11
+ } = useInternal();
12
+ let AnimatedIcon = Animated.createAnimatedComponent(iconComponent);
13
+ const iconProps = useAnimatedProps(() => {
14
+ return {
15
+ color: theme.value === 'light' ? 'black' : 'white'
16
+ };
17
+ }, [theme]);
18
+ return /*#__PURE__*/React.createElement(AnimatedIcon, {
19
+ name: name,
20
+ size: 18,
21
+ animatedProps: iconProps
22
+ });
23
+ };
24
+
25
+ export default /*#__PURE__*/memo(Icon);
26
+ //# sourceMappingURL=Icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["Icon.tsx"],"names":["React","memo","Animated","useAnimatedProps","useInternal","Icon","iconComponent","name","theme","AnimatedIcon","createAnimatedComponent","iconProps","color","value"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,IAAhB,QAA4B,OAA5B;AAEA,OAAOC,QAAP,IAAmBC,gBAAnB,QAA2C,yBAA3C;AACA,SAASC,WAAT,QAA4B,aAA5B;;AAcA,MAAMC,IAAI,GAAG,CAAC;AAAEC,EAAAA,aAAF;AAAiBC,EAAAA;AAAjB,CAAD,KAAwC;AACnD,QAAM;AAAEC,IAAAA;AAAF,MAAYJ,WAAW,EAA7B;AACA,MAAIK,YAAY,GAAGP,QAAQ,CAACQ,uBAAT,CACjBJ,aADiB,CAAnB;AAIA,QAAMK,SAAS,GAAGR,gBAAgB,CAAC,MAAM;AACvC,WAAO;AACLS,MAAAA,KAAK,EAAEJ,KAAK,CAACK,KAAN,KAAgB,OAAhB,GAA0B,OAA1B,GAAoC;AADtC,KAAP;AAGD,GAJiC,EAI/B,CAACL,KAAD,CAJ+B,CAAlC;AAMA,sBAAO,oBAAC,YAAD;AAAc,IAAA,IAAI,EAAED,IAApB;AAA0B,IAAA,IAAI,EAAE,EAAhC;AAAoC,IAAA,aAAa,EAAEI;AAAnD,IAAP;AACD,CAbD;;AAeA,4BAAeV,IAAI,CAACI,IAAD,CAAnB","sourcesContent":["import React, { memo } from 'react';\n\nimport Animated, { useAnimatedProps } from 'react-native-reanimated';\nimport { useInternal } from '../../hooks';\n\ntype IconComponentProps = {\n name: string;\n size: number;\n animatedProps: Partial<{ color: string }>;\n};\n\n// Update iconComponent type, React.ComponentClass<IconComponentProps, any>\ntype IconProps = {\n iconComponent: any;\n name: string;\n};\n\nconst Icon = ({ iconComponent, name }: IconProps) => {\n const { theme } = useInternal();\n let AnimatedIcon = Animated.createAnimatedComponent<IconComponentProps>(\n iconComponent\n );\n\n const iconProps = useAnimatedProps(() => {\n return {\n color: theme.value === 'light' ? 'black' : 'white',\n };\n }, [theme]);\n\n return <AnimatedIcon name={name} size={18} animatedProps={iconProps} />;\n};\n\nexport default memo(Icon);\n"]}
@@ -0,0 +1,2 @@
1
+ export { default } from './Icon';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.ts"],"names":["default"],"mappings":"AAAA,SAASA,OAAT,QAAwB,QAAxB","sourcesContent":["export { default } from './Icon';\n"]}
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import Animated, { useAnimatedStyle, withSpring, withTiming } from 'react-native-reanimated';
3
+ import MenuList from './MenuList';
4
+ import styles from './styles';
5
+ import { useInternal } from '../../hooks';
6
+ import { HOLD_ITEM_TRANSFORM_DURATION, CONTEXT_MENU_STATE, SPRING_CONFIGURATION } from '../../constants';
7
+
8
+ const MenuComponent = () => {
9
+ const {
10
+ state,
11
+ menuProps
12
+ } = useInternal();
13
+ const wrapperStyles = useAnimatedStyle(() => {
14
+ const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
15
+ const top = anchorPositionVertical === 'top' ? menuProps.value.itemHeight + menuProps.value.itemY + 8 : menuProps.value.itemY - 8;
16
+ const left = menuProps.value.itemX;
17
+ const width = menuProps.value.itemWidth;
18
+ const tY = menuProps.value.transformValue;
19
+ return {
20
+ top,
21
+ left,
22
+ width,
23
+ transform: [{
24
+ translateY: state.value === CONTEXT_MENU_STATE.ACTIVE ? withSpring(tY, SPRING_CONFIGURATION) : withTiming(0, {
25
+ duration: HOLD_ITEM_TRANSFORM_DURATION
26
+ })
27
+ }]
28
+ };
29
+ }, [menuProps]);
30
+ return /*#__PURE__*/React.createElement(Animated.View, {
31
+ style: [styles.menuWrapper, wrapperStyles]
32
+ }, /*#__PURE__*/React.createElement(MenuList, null));
33
+ };
34
+
35
+ const Menu = /*#__PURE__*/React.memo(MenuComponent);
36
+ export default Menu;
37
+ //# sourceMappingURL=Menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["Menu.tsx"],"names":["React","Animated","useAnimatedStyle","withSpring","withTiming","MenuList","styles","useInternal","HOLD_ITEM_TRANSFORM_DURATION","CONTEXT_MENU_STATE","SPRING_CONFIGURATION","MenuComponent","state","menuProps","wrapperStyles","anchorPositionVertical","value","anchorPosition","split","top","itemHeight","itemY","left","itemX","width","itemWidth","tY","transformValue","transform","translateY","ACTIVE","duration","menuWrapper","Menu","memo"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AAEA,OAAOC,QAAP,IACEC,gBADF,EAEEC,UAFF,EAGEC,UAHF,QAIO,yBAJP;AAMA,OAAOC,QAAP,MAAqB,YAArB;AAEA,OAAOC,MAAP,MAAmB,UAAnB;AACA,SAASC,WAAT,QAA4B,aAA5B;AACA,SACEC,4BADF,EAEEC,kBAFF,EAGEC,oBAHF,QAIO,iBAJP;;AAMA,MAAMC,aAAa,GAAG,MAAM;AAC1B,QAAM;AAAEC,IAAAA,KAAF;AAASC,IAAAA;AAAT,MAAuBN,WAAW,EAAxC;AAEA,QAAMO,aAAa,GAAGZ,gBAAgB,CAAC,MAAM;AAC3C,UAAMa,sBAAsB,GAAGF,SAAS,CAACG,KAAV,CAAgBC,cAAhB,CAA+BC,KAA/B,CAAqC,GAArC,EAA0C,CAA1C,CAA/B;AAEA,UAAMC,GAAG,GACPJ,sBAAsB,KAAK,KAA3B,GACIF,SAAS,CAACG,KAAV,CAAgBI,UAAhB,GAA6BP,SAAS,CAACG,KAAV,CAAgBK,KAA7C,GAAqD,CADzD,GAEIR,SAAS,CAACG,KAAV,CAAgBK,KAAhB,GAAwB,CAH9B;AAIA,UAAMC,IAAI,GAAGT,SAAS,CAACG,KAAV,CAAgBO,KAA7B;AACA,UAAMC,KAAK,GAAGX,SAAS,CAACG,KAAV,CAAgBS,SAA9B;AACA,UAAMC,EAAE,GAAGb,SAAS,CAACG,KAAV,CAAgBW,cAA3B;AAEA,WAAO;AACLR,MAAAA,GADK;AAELG,MAAAA,IAFK;AAGLE,MAAAA,KAHK;AAILI,MAAAA,SAAS,EAAE,CACT;AACEC,QAAAA,UAAU,EACRjB,KAAK,CAACI,KAAN,KAAgBP,kBAAkB,CAACqB,MAAnC,GACI3B,UAAU,CAACuB,EAAD,EAAKhB,oBAAL,CADd,GAEIN,UAAU,CAAC,CAAD,EAAI;AAAE2B,UAAAA,QAAQ,EAAEvB;AAAZ,SAAJ;AAJlB,OADS;AAJN,KAAP;AAaD,GAxBqC,EAwBnC,CAACK,SAAD,CAxBmC,CAAtC;AA0BA,sBACE,oBAAC,QAAD,CAAU,IAAV;AAAe,IAAA,KAAK,EAAE,CAACP,MAAM,CAAC0B,WAAR,EAAqBlB,aAArB;AAAtB,kBACE,oBAAC,QAAD,OADF,CADF;AAKD,CAlCD;;AAoCA,MAAMmB,IAAI,gBAAGjC,KAAK,CAACkC,IAAN,CAAWvB,aAAX,CAAb;AAEA,eAAesB,IAAf","sourcesContent":["import React from 'react';\n\nimport Animated, {\n useAnimatedStyle,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\n\nimport MenuList from './MenuList';\n\nimport styles from './styles';\nimport { useInternal } from '../../hooks';\nimport {\n HOLD_ITEM_TRANSFORM_DURATION,\n CONTEXT_MENU_STATE,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst MenuComponent = () => {\n const { state, menuProps } = useInternal();\n\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemHeight + menuProps.value.itemY + 8\n : menuProps.value.itemY - 8;\n const left = menuProps.value.itemX;\n const width = menuProps.value.itemWidth;\n const tY = menuProps.value.transformValue;\n\n return {\n top,\n left,\n width,\n transform: [\n {\n translateY:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),\n },\n ],\n };\n }, [menuProps]);\n\n return (\n <Animated.View style={[styles.menuWrapper, wrapperStyles]}>\n <MenuList />\n </Animated.View>\n );\n};\n\nconst Menu = React.memo(MenuComponent);\n\nexport default Menu;\n"]}
@@ -0,0 +1,59 @@
1
+ import React, { useCallback } from 'react';
2
+ import { TouchableOpacity } from 'react-native';
3
+ import Animated, { useAnimatedStyle } from 'react-native-reanimated';
4
+ import Separator from './Separator';
5
+ import styles from './styles';
6
+ import { useInternal } from '../../hooks';
7
+ import { CONTEXT_MENU_STATE } from '../../constants';
8
+ import { BORDER_LIGHT_COLOR, BORDER_DARK_COLOR } from './constants';
9
+ import isEqual from 'lodash.isequal';
10
+ import { getColor } from './calculations';
11
+ import { AnimatedIcon } from '../provider/Provider'; // @ts-ignore
12
+
13
+ const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity);
14
+
15
+ const MenuItemComponent = ({
16
+ item,
17
+ isLast
18
+ }) => {
19
+ const {
20
+ state,
21
+ theme,
22
+ menuProps
23
+ } = useInternal();
24
+ const borderStyles = useAnimatedStyle(() => {
25
+ const borderBottomColor = theme.value === 'dark' ? BORDER_DARK_COLOR : BORDER_LIGHT_COLOR;
26
+ return {
27
+ borderBottomColor,
28
+ borderBottomWidth: isLast ? 0 : 1
29
+ };
30
+ }, [theme, isLast, item]);
31
+ const textColor = useAnimatedStyle(() => {
32
+ return {
33
+ color: getColor(item.isTitle, item.isDestructive, theme.value)
34
+ };
35
+ }, [theme, item]);
36
+ const handleOnPress = useCallback(() => {
37
+ if (!item.isTitle) {
38
+ const params = menuProps.value.actionParams[item.text] || [];
39
+ if (item.onPress) item.onPress(...params);
40
+ state.value = CONTEXT_MENU_STATE.END;
41
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
42
+
43
+ }, [state, item]);
44
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(AnimatedTouchable, {
45
+ onPress: handleOnPress,
46
+ activeOpacity: !item.isTitle ? 0.4 : 1,
47
+ style: [styles.menuItem, borderStyles]
48
+ }, /*#__PURE__*/React.createElement(Animated.Text, {
49
+ style: [item.isTitle ? styles.menuItemTitleText : styles.menuItemText, textColor]
50
+ }, item.text), !item.isTitle && item.icon && (AnimatedIcon && typeof item.icon === 'string' ? /*#__PURE__*/React.createElement(AnimatedIcon, {
51
+ name: item.icon,
52
+ size: 18,
53
+ style: textColor
54
+ }) : typeof item.icon === 'function' ? item.icon() : null)), item.withSeparator && /*#__PURE__*/React.createElement(Separator, null));
55
+ };
56
+
57
+ const MenuItem = /*#__PURE__*/React.memo(MenuItemComponent, isEqual);
58
+ export default MenuItem;
59
+ //# sourceMappingURL=MenuItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["MenuItem.tsx"],"names":["React","useCallback","TouchableOpacity","Animated","useAnimatedStyle","Separator","styles","useInternal","CONTEXT_MENU_STATE","BORDER_LIGHT_COLOR","BORDER_DARK_COLOR","isEqual","getColor","AnimatedIcon","AnimatedTouchable","createAnimatedComponent","MenuItemComponent","item","isLast","state","theme","menuProps","borderStyles","borderBottomColor","value","borderBottomWidth","textColor","color","isTitle","isDestructive","handleOnPress","params","actionParams","text","onPress","END","menuItem","menuItemTitleText","menuItemText","icon","withSeparator","MenuItem","memo"],"mappings":"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","sourcesContent":["import React, { useCallback } from 'react';\nimport { TouchableOpacity } from 'react-native';\nimport Animated, { useAnimatedStyle } from 'react-native-reanimated';\n\nimport Separator from './Separator';\nimport styles from './styles';\n\nimport { MenuItemProps } from './types';\nimport { useInternal } from '../../hooks';\nimport { CONTEXT_MENU_STATE } from '../../constants';\nimport { BORDER_LIGHT_COLOR, BORDER_DARK_COLOR } from './constants';\nimport isEqual from 'lodash.isequal';\nimport { getColor } from './calculations';\nimport { AnimatedIcon } from '../provider/Provider';\n\n// @ts-ignore\nconst AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity);\n\ntype MenuItemComponentProps = {\n item: MenuItemProps;\n isLast?: boolean;\n};\n\nconst MenuItemComponent = ({ item, isLast }: MenuItemComponentProps) => {\n const { state, theme, menuProps } = useInternal();\n\n const borderStyles = useAnimatedStyle(() => {\n const borderBottomColor =\n theme.value === 'dark' ? BORDER_DARK_COLOR : BORDER_LIGHT_COLOR;\n\n return {\n borderBottomColor,\n borderBottomWidth: isLast ? 0 : 1,\n };\n }, [theme, isLast, item]);\n\n const textColor = useAnimatedStyle(() => {\n return { color: getColor(item.isTitle, item.isDestructive, theme.value) };\n }, [theme, item]);\n\n const handleOnPress = useCallback(() => {\n if (!item.isTitle) {\n const params = menuProps.value.actionParams[item.text] || [];\n if (item.onPress) item.onPress(...params);\n state.value = CONTEXT_MENU_STATE.END;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state, item]);\n\n return (\n <>\n <AnimatedTouchable\n onPress={handleOnPress}\n activeOpacity={!item.isTitle ? 0.4 : 1}\n style={[styles.menuItem, borderStyles]}\n >\n <Animated.Text\n style={[\n item.isTitle ? styles.menuItemTitleText : styles.menuItemText,\n textColor,\n ]}\n >\n {item.text}\n </Animated.Text>\n {!item.isTitle &&\n item.icon &&\n (AnimatedIcon && typeof item.icon === 'string' ? (\n <AnimatedIcon name={item.icon} size={18} style={textColor} />\n ) : typeof item.icon === 'function' ? (\n item.icon()\n ) : null)}\n </AnimatedTouchable>\n {item.withSeparator && <Separator />}\n </>\n );\n};\n\nconst MenuItem = React.memo(MenuItemComponent, isEqual);\nexport default MenuItem;\n"]}
@@ -0,0 +1,19 @@
1
+ import React, { memo } from 'react';
2
+ import MenuItem from './MenuItem';
3
+ import isEqual from 'lodash.isequal';
4
+
5
+ const MenuItemsComponent = ({
6
+ items
7
+ }) => {
8
+ return /*#__PURE__*/React.createElement(React.Fragment, null, items.map((item, index) => {
9
+ return /*#__PURE__*/React.createElement(MenuItem, {
10
+ key: index,
11
+ item: item,
12
+ isLast: items.length === index + 1
13
+ });
14
+ }));
15
+ };
16
+
17
+ const MenuItems = /*#__PURE__*/memo(MenuItemsComponent, isEqual);
18
+ export default MenuItems;
19
+ //# sourceMappingURL=MenuItems.js.map