react-native-hold-menu-actions 0.1.11 → 0.1.14

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 (54) hide show
  1. package/lib/commonjs/components/backdrop/Backdrop.js +3 -6
  2. package/lib/commonjs/components/backdrop/Backdrop.js.map +1 -1
  3. package/lib/commonjs/components/customView/CustomView.js +142 -0
  4. package/lib/commonjs/components/customView/CustomView.js.map +1 -0
  5. package/lib/commonjs/components/holdItem/HoldItem.js +19 -24
  6. package/lib/commonjs/components/holdItem/HoldItem.js.map +1 -1
  7. package/lib/commonjs/components/menu/Menu.js +1 -3
  8. package/lib/commonjs/components/menu/Menu.js.map +1 -1
  9. package/lib/commonjs/components/menu/MenuList.js +13 -3
  10. package/lib/commonjs/components/menu/MenuList.js.map +1 -1
  11. package/lib/commonjs/components/provider/Provider.js +6 -5
  12. package/lib/commonjs/components/provider/Provider.js.map +1 -1
  13. package/lib/commonjs/context/internal.js.map +1 -1
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/module/components/backdrop/Backdrop.js +3 -6
  16. package/lib/module/components/backdrop/Backdrop.js.map +1 -1
  17. package/lib/module/components/customView/CustomView.js +124 -0
  18. package/lib/module/components/customView/CustomView.js.map +1 -0
  19. package/lib/module/components/holdItem/HoldItem.js +20 -24
  20. package/lib/module/components/holdItem/HoldItem.js.map +1 -1
  21. package/lib/module/components/menu/Menu.js +1 -3
  22. package/lib/module/components/menu/Menu.js.map +1 -1
  23. package/lib/module/components/menu/MenuList.js +13 -5
  24. package/lib/module/components/menu/MenuList.js.map +1 -1
  25. package/lib/module/components/provider/Provider.js +6 -5
  26. package/lib/module/components/provider/Provider.js.map +1 -1
  27. package/lib/module/context/internal.js.map +1 -1
  28. package/lib/module/index.js.map +1 -1
  29. package/lib/typescript/components/customView/CustomView.d.ts +3 -0
  30. package/lib/typescript/components/holdItem/HoldItem.d.ts +1 -1
  31. package/lib/typescript/components/holdItem/types.d.ts +13 -15
  32. package/lib/typescript/components/menu/types.d.ts +7 -0
  33. package/lib/typescript/components/provider/Provider.d.ts +1 -1
  34. package/lib/typescript/components/provider/types.d.ts +1 -1
  35. package/lib/typescript/context/internal.d.ts +3 -4
  36. package/lib/typescript/index.d.ts +2 -2
  37. package/package.json +1 -1
  38. package/src/components/backdrop/Backdrop.tsx +2 -5
  39. package/src/components/customView/CustomView.tsx +164 -0
  40. package/src/components/holdItem/HoldItem.tsx +20 -25
  41. package/src/components/holdItem/types.d.ts +13 -15
  42. package/src/components/menu/Menu.tsx +4 -5
  43. package/src/components/menu/MenuList.tsx +23 -4
  44. package/src/components/menu/types.d.ts +7 -0
  45. package/src/components/provider/Provider.tsx +16 -18
  46. package/src/components/provider/types.d.ts +1 -1
  47. package/src/context/internal.ts +3 -8
  48. package/src/index.ts +5 -4
  49. package/lib/commonjs/components/provider/Content.js +0 -74
  50. package/lib/commonjs/components/provider/Content.js.map +0 -1
  51. package/lib/module/components/provider/Content.js +0 -59
  52. package/lib/module/components/provider/Content.js.map +0 -1
  53. package/lib/typescript/components/provider/Content.d.ts +0 -2
  54. package/src/components/provider/Content.tsx +0 -93
@@ -29,18 +29,17 @@ const MenuComponent = () => {
29
29
  const left = menuProps.value.itemX;
30
30
  const width = menuProps.value.itemWidth;
31
31
  const tY = menuProps.value.transformValue;
32
- const isActive = state.value === CONTEXT_MENU_STATE.ACTIVE;
33
32
 
34
33
  return {
35
34
  top,
36
35
  left,
37
36
  width,
38
- pointerEvents: isActive ? 'auto' : 'none',
39
37
  transform: [
40
38
  {
41
- translateY: isActive
42
- ? withSpring(tY, SPRING_CONFIGURATION)
43
- : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),
39
+ translateY:
40
+ state.value === CONTEXT_MENU_STATE.ACTIVE
41
+ ? withSpring(tY, SPRING_CONFIGURATION)
42
+ : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),
44
43
  },
45
44
  ],
46
45
  };
@@ -3,6 +3,7 @@ import { StyleSheet } from 'react-native';
3
3
 
4
4
  import Animated, {
5
5
  runOnJS,
6
+ useAnimatedProps,
6
7
  useAnimatedReaction,
7
8
  useAnimatedStyle,
8
9
  useDerivedValue,
@@ -15,12 +16,14 @@ import {
15
16
  calculateMenuHeight,
16
17
  menuAnimationAnchor,
17
18
  } from '../../utils/calculations';
19
+ import { BlurView } from '@react-native-community/blur';
18
20
 
19
21
  import MenuItems from './MenuItems';
20
22
 
21
23
  import {
22
24
  SPRING_CONFIGURATION_MENU,
23
25
  HOLD_ITEM_TRANSFORM_DURATION,
26
+ IS_IOS,
24
27
  CONTEXT_MENU_STATE,
25
28
  } from '../../constants';
26
29
 
@@ -30,6 +33,8 @@ import { useInternal } from '../../hooks';
30
33
  import { deepEqual } from '../../utils/validations';
31
34
  import { leftOrRight } from './calculations';
32
35
 
36
+ const AnimatedView = Animated.createAnimatedComponent(BlurView);
37
+
33
38
  const MenuListComponent = () => {
34
39
  const { state, theme, menuProps } = useInternal();
35
40
 
@@ -89,12 +94,22 @@ const MenuListComponent = () => {
89
94
  });
90
95
 
91
96
  const animatedInnerContainerStyle = useAnimatedStyle(() => {
92
- const color = theme.value === 'light' ? '#fff' : '#1A1A1A';
93
97
  return {
94
- backgroundColor: color,
98
+ backgroundColor:
99
+ theme.value === 'light'
100
+ ? IS_IOS
101
+ ? 'rgba(255, 255, 255, .75)'
102
+ : 'rgba(255, 255, 255, .95)'
103
+ : IS_IOS
104
+ ? 'rgba(0,0,0,0.5)'
105
+ : 'rgba(39, 39, 39, .8)',
95
106
  };
96
107
  }, [theme]);
97
108
 
109
+ const animatedProps = useAnimatedProps(() => {
110
+ return { blurType: theme.value };
111
+ }, [theme]);
112
+
98
113
  const setter = (items: MenuItemProps[]) => {
99
114
  setItemList(items);
100
115
  prevList.value = items;
@@ -111,7 +126,11 @@ const MenuListComponent = () => {
111
126
  );
112
127
 
113
128
  return (
114
- <Animated.View style={[styles.menuContainer, messageStyles]}>
129
+ <AnimatedView
130
+ blurAmount={100}
131
+ animatedProps={animatedProps}
132
+ style={[styles.menuContainer, messageStyles]}
133
+ >
115
134
  <Animated.View
116
135
  style={[
117
136
  StyleSheet.absoluteFillObject,
@@ -121,7 +140,7 @@ const MenuListComponent = () => {
121
140
  >
122
141
  <MenuItems items={itemList} />
123
142
  </Animated.View>
124
- </Animated.View>
143
+ </AnimatedView>
125
144
  );
126
145
  };
127
146
 
@@ -13,6 +13,12 @@ export type MenuListProps = {
13
13
  items: MenuItemProps[];
14
14
  };
15
15
 
16
+ export type CustomViewProps = {
17
+ closeMenu: () => void;
18
+ };
19
+
20
+ export type RenderCustomView = (props: CustomViewProps) => React.ReactElement;
21
+
16
22
  export type MenuInternalProps = {
17
23
  items: MenuItemProps[];
18
24
  itemHeight: number;
@@ -25,4 +31,5 @@ export type MenuInternalProps = {
25
31
  actionParams: {
26
32
  [name: string]: (string | number)[];
27
33
  };
34
+ hasCustomView: boolean;
28
35
  };
@@ -1,10 +1,6 @@
1
1
  import React, { memo, useEffect, useMemo, useRef } from 'react';
2
2
  import { PortalProvider } from '@gorhom/portal';
3
- import Animated, {
4
- useSharedValue,
5
- useAnimatedReaction,
6
- runOnJS,
7
- } from 'react-native-reanimated';
3
+ import Animated, { useSharedValue, useAnimatedReaction, runOnJS } from 'react-native-reanimated';
8
4
  import { GestureHandlerRootView } from 'react-native-gesture-handler';
9
5
 
10
6
  // Components
@@ -17,7 +13,8 @@ import { StateProps, Action } from './reducer';
17
13
  import { CONTEXT_MENU_STATE } from '../../constants';
18
14
  import { MenuInternalProps } from '../menu/types';
19
15
  import Menu from '../menu';
20
- import Content from './Content';
16
+ import CustomView from '../customView/CustomView';
17
+ import { RenderCustomView } from '../menu/types';
21
18
 
22
19
  export interface Store {
23
20
  state: StateProps;
@@ -26,14 +23,14 @@ export interface Store {
26
23
 
27
24
  export let AnimatedIcon: any;
28
25
 
29
- const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
26
+ const ProviderComponent = ({
30
27
  children,
31
28
  theme: selectedTheme,
32
29
  iconComponent,
33
30
  safeAreaInsets,
34
31
  onOpen,
35
32
  onClose,
36
- }) => {
33
+ }: HoldMenuProviderProps) => {
37
34
  if (iconComponent)
38
35
  AnimatedIcon = Animated.createAnimatedComponent(iconComponent);
39
36
 
@@ -51,10 +48,9 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
51
48
  menuHeight: 0,
52
49
  transformValue: 0,
53
50
  actionParams: {},
51
+ hasCustomView: false,
54
52
  });
55
- const contentRenderer = useRef<((params: any) => React.ReactNode) | null>(
56
- null
57
- );
53
+ const customViewRef = useRef<RenderCustomView | null>(null);
58
54
 
59
55
  useEffect(() => {
60
56
  theme.value = selectedTheme || 'light';
@@ -66,12 +62,14 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
66
62
  state => {
67
63
  switch (state) {
68
64
  case CONTEXT_MENU_STATE.ACTIVE: {
69
- if (onOpen) runOnJS(onOpen)();
70
- break;
65
+ if (onOpen)
66
+ runOnJS(onOpen)();
67
+ break
71
68
  }
72
69
  case CONTEXT_MENU_STATE.END: {
73
- if (onClose) runOnJS(onClose)();
74
- break;
70
+ if (onClose)
71
+ runOnJS(onClose)();
72
+ break
75
73
  }
76
74
  }
77
75
  },
@@ -83,7 +81,7 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
83
81
  state,
84
82
  theme,
85
83
  menuProps,
86
- contentRenderer,
84
+ customViewRef,
87
85
  safeAreaInsets: safeAreaInsets || {
88
86
  top: 0,
89
87
  bottom: 0,
@@ -101,13 +99,13 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
101
99
  {children}
102
100
  <Backdrop />
103
101
  <Menu />
104
- <Content />
102
+ <CustomView />
105
103
  </PortalProvider>
106
104
  </InternalContext.Provider>
107
105
  </GestureHandlerRootView>
108
106
  );
109
107
  };
110
108
 
111
- const Provider = memo(ProviderComponent) as React.FC<HoldMenuProviderProps>;
109
+ const Provider = memo(ProviderComponent);
112
110
 
113
111
  export default Provider;
@@ -21,7 +21,7 @@ export interface HoldMenuProviderProps {
21
21
  * safeAreaInsets={insets}
22
22
  * ```
23
23
  */
24
- safeAreaInsets?: {
24
+ safeAreaInsets: {
25
25
  top: number;
26
26
  right: number;
27
27
  bottom: number;
@@ -1,18 +1,13 @@
1
- import { createContext } from 'react';
2
- import type { MutableRefObject } from 'react';
1
+ import { createContext, MutableRefObject } from 'react';
3
2
  import type Animated from 'react-native-reanimated';
4
3
  import type { CONTEXT_MENU_STATE } from '../constants';
5
- import { MenuInternalProps } from '../components/menu/types';
6
-
7
- export type ContentRendererRef = MutableRefObject<
8
- ((params: any) => React.ReactNode) | null
9
- >;
4
+ import { MenuInternalProps, RenderCustomView } from '../components/menu/types';
10
5
 
11
6
  export type InternalContextType = {
12
7
  state: Animated.SharedValue<CONTEXT_MENU_STATE>;
13
8
  theme: Animated.SharedValue<'light' | 'dark'>;
14
9
  menuProps: Animated.SharedValue<MenuInternalProps>;
15
- contentRenderer: ContentRendererRef;
10
+ customViewRef: MutableRefObject<RenderCustomView | null>;
16
11
  safeAreaInsets?: {
17
12
  top: number;
18
13
  right: number;
package/src/index.ts CHANGED
@@ -3,8 +3,9 @@ export { default as HoldMenuProvider } from './components/provider';
3
3
  export { default as HoldMenuFlatList } from './components/flatList';
4
4
  export { default as HoldMenuIcon } from './components/icon';
5
5
 
6
- export type { HoldMenuProviderProps } from './components/provider';
6
+ export type { HoldItemProps } from './components/holdItem/types';
7
7
  export type {
8
- HoldItemProps,
9
- RenderContentParams,
10
- } from './components/holdItem/types';
8
+ MenuItemProps,
9
+ CustomViewProps,
10
+ RenderCustomView,
11
+ } from './components/menu/types';
@@ -1,74 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _react = _interopRequireWildcard(require("react"));
9
-
10
- var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
11
-
12
- var _hooks = require("../../hooks");
13
-
14
- var _constants = require("../../constants");
15
-
16
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
17
-
18
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
-
20
- const Content = () => {
21
- const {
22
- state,
23
- menuProps,
24
- contentRenderer
25
- } = (0, _hooks.useInternal)();
26
- const [isActive, setIsActive] = (0, _react.useState)(false);
27
- const contentHeight = (0, _reactNativeReanimated.useSharedValue)(0);
28
- const handleLayout = (0, _react.useCallback)(event => {
29
- contentHeight.value = event.nativeEvent.layout.height;
30
- }, [contentHeight]); // синхронизируем Reanimated state → React state
31
-
32
- (0, _reactNativeReanimated.useAnimatedReaction)(() => state.value, val => {
33
- (0, _reactNativeReanimated.runOnJS)(setIsActive)(val === _constants.CONTEXT_MENU_STATE.ACTIVE);
34
- });
35
- const renderContent = contentRenderer.current;
36
- const wrapperStyles = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
37
- const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
38
- const anchorPositionHorizontal = menuProps.value.anchorPosition.split('-')[1];
39
- const top = anchorPositionVertical === 'top' ? menuProps.value.itemY - contentHeight.value - 8 : menuProps.value.itemY + menuProps.value.itemHeight + 8;
40
- const left = anchorPositionHorizontal === 'center' ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3 : anchorPositionHorizontal === 'right' ? undefined : menuProps.value.itemX;
41
- const right = anchorPositionHorizontal === 'right' ? 0 : undefined;
42
- const tY = menuProps.value.transformValue;
43
- return {
44
- opacity: state.value === _constants.CONTEXT_MENU_STATE.ACTIVE ? (0, _reactNativeReanimated.withTiming)(1) : (0, _reactNativeReanimated.withTiming)(0),
45
- top,
46
- left,
47
- right,
48
- transform: [{
49
- translateY: state.value === _constants.CONTEXT_MENU_STATE.ACTIVE ? (0, _reactNativeReanimated.withSpring)(tY, _constants.SPRING_CONFIGURATION) : (0, _reactNativeReanimated.withTiming)(0, {
50
- duration: _constants.HOLD_ITEM_TRANSFORM_DURATION
51
- })
52
- }]
53
- };
54
- }, [menuProps]);
55
-
56
- const closeMenu = () => state.value = _constants.CONTEXT_MENU_STATE.END;
57
-
58
- if (!renderContent) {
59
- return null;
60
- }
61
-
62
- return /*#__PURE__*/_react.default.createElement(_reactNativeReanimated.default.View, {
63
- onLayout: handleLayout,
64
- style: [{
65
- position: 'absolute',
66
- left: 0,
67
- zIndex: 12
68
- }, wrapperStyles]
69
- }, isActive && renderContent(closeMenu));
70
- };
71
-
72
- var _default = Content;
73
- exports.default = _default;
74
- //# sourceMappingURL=Content.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["Content.tsx"],"names":["Content","state","menuProps","contentRenderer","isActive","setIsActive","contentHeight","handleLayout","event","value","nativeEvent","layout","height","val","CONTEXT_MENU_STATE","ACTIVE","renderContent","current","wrapperStyles","anchorPositionVertical","anchorPosition","split","anchorPositionHorizontal","top","itemY","itemHeight","left","itemX","itemWidth","undefined","right","tY","transformValue","opacity","transform","translateY","SPRING_CONFIGURATION","duration","HOLD_ITEM_TRANSFORM_DURATION","closeMenu","END","position","zIndex"],"mappings":"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","sourcesContent":["import React, { useCallback, useState } from 'react';\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n useSharedValue,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\nimport type { LayoutChangeEvent } from 'react-native';\nimport { useInternal } from '../../hooks';\nimport {\n CONTEXT_MENU_STATE,\n HOLD_ITEM_TRANSFORM_DURATION,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst Content = () => {\n const { state, menuProps, contentRenderer } = useInternal();\n const [isActive, setIsActive] = useState(false);\n const contentHeight = useSharedValue(0);\n\n const handleLayout = useCallback(\n (event: LayoutChangeEvent) => {\n contentHeight.value = event.nativeEvent.layout.height;\n },\n [contentHeight]\n );\n\n // синхронизируем Reanimated state → React state\n useAnimatedReaction(\n () => state.value,\n val => {\n runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);\n }\n );\n\n const renderContent = contentRenderer.current;\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n const anchorPositionHorizontal = menuProps.value.anchorPosition.split(\n '-'\n )[1];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemY - contentHeight.value - 8\n : menuProps.value.itemY + menuProps.value.itemHeight + 8;\n\n const left =\n anchorPositionHorizontal === 'center'\n ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3\n : anchorPositionHorizontal === 'right'\n ? undefined\n : menuProps.value.itemX;\n const right = anchorPositionHorizontal === 'right' ? 0 : undefined;\n\n const tY = menuProps.value.transformValue;\n return {\n opacity:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withTiming(1)\n : withTiming(0),\n top,\n left,\n right,\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 const closeMenu = () => (state.value = CONTEXT_MENU_STATE.END);\n\n if (!renderContent) {\n return null;\n }\n return (\n <Animated.View\n onLayout={handleLayout}\n style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}\n >\n {isActive && renderContent(closeMenu)}\n </Animated.View>\n );\n};\n\nexport default Content;\n"]}
@@ -1,59 +0,0 @@
1
- import React, { useCallback, useState } from 'react';
2
- import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
3
- import { useInternal } from '../../hooks';
4
- import { CONTEXT_MENU_STATE, HOLD_ITEM_TRANSFORM_DURATION, SPRING_CONFIGURATION } from '../../constants';
5
-
6
- const Content = () => {
7
- const {
8
- state,
9
- menuProps,
10
- contentRenderer
11
- } = useInternal();
12
- const [isActive, setIsActive] = useState(false);
13
- const contentHeight = useSharedValue(0);
14
- const handleLayout = useCallback(event => {
15
- contentHeight.value = event.nativeEvent.layout.height;
16
- }, [contentHeight]); // синхронизируем Reanimated state → React state
17
-
18
- useAnimatedReaction(() => state.value, val => {
19
- runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);
20
- });
21
- const renderContent = contentRenderer.current;
22
- const wrapperStyles = useAnimatedStyle(() => {
23
- const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
24
- const anchorPositionHorizontal = menuProps.value.anchorPosition.split('-')[1];
25
- const top = anchorPositionVertical === 'top' ? menuProps.value.itemY - contentHeight.value - 8 : menuProps.value.itemY + menuProps.value.itemHeight + 8;
26
- const left = anchorPositionHorizontal === 'center' ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3 : anchorPositionHorizontal === 'right' ? undefined : menuProps.value.itemX;
27
- const right = anchorPositionHorizontal === 'right' ? 0 : undefined;
28
- const tY = menuProps.value.transformValue;
29
- return {
30
- opacity: state.value === CONTEXT_MENU_STATE.ACTIVE ? withTiming(1) : withTiming(0),
31
- top,
32
- left,
33
- right,
34
- transform: [{
35
- translateY: state.value === CONTEXT_MENU_STATE.ACTIVE ? withSpring(tY, SPRING_CONFIGURATION) : withTiming(0, {
36
- duration: HOLD_ITEM_TRANSFORM_DURATION
37
- })
38
- }]
39
- };
40
- }, [menuProps]);
41
-
42
- const closeMenu = () => state.value = CONTEXT_MENU_STATE.END;
43
-
44
- if (!renderContent) {
45
- return null;
46
- }
47
-
48
- return /*#__PURE__*/React.createElement(Animated.View, {
49
- onLayout: handleLayout,
50
- style: [{
51
- position: 'absolute',
52
- left: 0,
53
- zIndex: 12
54
- }, wrapperStyles]
55
- }, isActive && renderContent(closeMenu));
56
- };
57
-
58
- export default Content;
59
- //# sourceMappingURL=Content.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["Content.tsx"],"names":["React","useCallback","useState","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","useSharedValue","withSpring","withTiming","useInternal","CONTEXT_MENU_STATE","HOLD_ITEM_TRANSFORM_DURATION","SPRING_CONFIGURATION","Content","state","menuProps","contentRenderer","isActive","setIsActive","contentHeight","handleLayout","event","value","nativeEvent","layout","height","val","ACTIVE","renderContent","current","wrapperStyles","anchorPositionVertical","anchorPosition","split","anchorPositionHorizontal","top","itemY","itemHeight","left","itemX","itemWidth","undefined","right","tY","transformValue","opacity","transform","translateY","duration","closeMenu","END","position","zIndex"],"mappings":"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","sourcesContent":["import React, { useCallback, useState } from 'react';\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n useSharedValue,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\nimport type { LayoutChangeEvent } from 'react-native';\nimport { useInternal } from '../../hooks';\nimport {\n CONTEXT_MENU_STATE,\n HOLD_ITEM_TRANSFORM_DURATION,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst Content = () => {\n const { state, menuProps, contentRenderer } = useInternal();\n const [isActive, setIsActive] = useState(false);\n const contentHeight = useSharedValue(0);\n\n const handleLayout = useCallback(\n (event: LayoutChangeEvent) => {\n contentHeight.value = event.nativeEvent.layout.height;\n },\n [contentHeight]\n );\n\n // синхронизируем Reanimated state → React state\n useAnimatedReaction(\n () => state.value,\n val => {\n runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);\n }\n );\n\n const renderContent = contentRenderer.current;\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n const anchorPositionHorizontal = menuProps.value.anchorPosition.split(\n '-'\n )[1];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemY - contentHeight.value - 8\n : menuProps.value.itemY + menuProps.value.itemHeight + 8;\n\n const left =\n anchorPositionHorizontal === 'center'\n ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3\n : anchorPositionHorizontal === 'right'\n ? undefined\n : menuProps.value.itemX;\n const right = anchorPositionHorizontal === 'right' ? 0 : undefined;\n\n const tY = menuProps.value.transformValue;\n return {\n opacity:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withTiming(1)\n : withTiming(0),\n top,\n left,\n right,\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 const closeMenu = () => (state.value = CONTEXT_MENU_STATE.END);\n\n if (!renderContent) {\n return null;\n }\n return (\n <Animated.View\n onLayout={handleLayout}\n style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}\n >\n {isActive && renderContent(closeMenu)}\n </Animated.View>\n );\n};\n\nexport default Content;\n"]}
@@ -1,2 +0,0 @@
1
- declare const Content: () => JSX.Element | null;
2
- export default Content;
@@ -1,93 +0,0 @@
1
- import React, { useCallback, useState } from 'react';
2
- import Animated, {
3
- runOnJS,
4
- useAnimatedReaction,
5
- useAnimatedStyle,
6
- useSharedValue,
7
- withSpring,
8
- withTiming,
9
- } from 'react-native-reanimated';
10
- import type { LayoutChangeEvent } from 'react-native';
11
- import { useInternal } from '../../hooks';
12
- import {
13
- CONTEXT_MENU_STATE,
14
- HOLD_ITEM_TRANSFORM_DURATION,
15
- SPRING_CONFIGURATION,
16
- } from '../../constants';
17
-
18
- const Content = () => {
19
- const { state, menuProps, contentRenderer } = useInternal();
20
- const [isActive, setIsActive] = useState(false);
21
- const contentHeight = useSharedValue(0);
22
-
23
- const handleLayout = useCallback(
24
- (event: LayoutChangeEvent) => {
25
- contentHeight.value = event.nativeEvent.layout.height;
26
- },
27
- [contentHeight]
28
- );
29
-
30
- // синхронизируем Reanimated state → React state
31
- useAnimatedReaction(
32
- () => state.value,
33
- val => {
34
- runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);
35
- }
36
- );
37
-
38
- const renderContent = contentRenderer.current;
39
- const wrapperStyles = useAnimatedStyle(() => {
40
- const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
41
- const anchorPositionHorizontal = menuProps.value.anchorPosition.split(
42
- '-'
43
- )[1];
44
-
45
- const top =
46
- anchorPositionVertical === 'top'
47
- ? menuProps.value.itemY - contentHeight.value - 8
48
- : menuProps.value.itemY + menuProps.value.itemHeight + 8;
49
-
50
- const left =
51
- anchorPositionHorizontal === 'center'
52
- ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3
53
- : anchorPositionHorizontal === 'right'
54
- ? undefined
55
- : menuProps.value.itemX;
56
- const right = anchorPositionHorizontal === 'right' ? 0 : undefined;
57
-
58
- const tY = menuProps.value.transformValue;
59
- return {
60
- opacity:
61
- state.value === CONTEXT_MENU_STATE.ACTIVE
62
- ? withTiming(1)
63
- : withTiming(0),
64
- top,
65
- left,
66
- right,
67
- transform: [
68
- {
69
- translateY:
70
- state.value === CONTEXT_MENU_STATE.ACTIVE
71
- ? withSpring(tY, SPRING_CONFIGURATION)
72
- : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),
73
- },
74
- ],
75
- };
76
- }, [menuProps]);
77
-
78
- const closeMenu = () => (state.value = CONTEXT_MENU_STATE.END);
79
-
80
- if (!renderContent) {
81
- return null;
82
- }
83
- return (
84
- <Animated.View
85
- onLayout={handleLayout}
86
- style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}
87
- >
88
- {isActive && renderContent(closeMenu)}
89
- </Animated.View>
90
- );
91
- };
92
-
93
- export default Content;