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.
- package/lib/commonjs/components/backdrop/Backdrop.js +3 -6
- package/lib/commonjs/components/backdrop/Backdrop.js.map +1 -1
- package/lib/commonjs/components/customView/CustomView.js +142 -0
- package/lib/commonjs/components/customView/CustomView.js.map +1 -0
- package/lib/commonjs/components/holdItem/HoldItem.js +19 -24
- package/lib/commonjs/components/holdItem/HoldItem.js.map +1 -1
- package/lib/commonjs/components/menu/Menu.js +1 -3
- package/lib/commonjs/components/menu/Menu.js.map +1 -1
- package/lib/commonjs/components/menu/MenuList.js +13 -3
- package/lib/commonjs/components/menu/MenuList.js.map +1 -1
- package/lib/commonjs/components/provider/Provider.js +6 -5
- package/lib/commonjs/components/provider/Provider.js.map +1 -1
- package/lib/commonjs/context/internal.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/components/backdrop/Backdrop.js +3 -6
- package/lib/module/components/backdrop/Backdrop.js.map +1 -1
- package/lib/module/components/customView/CustomView.js +124 -0
- package/lib/module/components/customView/CustomView.js.map +1 -0
- package/lib/module/components/holdItem/HoldItem.js +20 -24
- package/lib/module/components/holdItem/HoldItem.js.map +1 -1
- package/lib/module/components/menu/Menu.js +1 -3
- package/lib/module/components/menu/Menu.js.map +1 -1
- package/lib/module/components/menu/MenuList.js +13 -5
- package/lib/module/components/menu/MenuList.js.map +1 -1
- package/lib/module/components/provider/Provider.js +6 -5
- package/lib/module/components/provider/Provider.js.map +1 -1
- package/lib/module/context/internal.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/components/customView/CustomView.d.ts +3 -0
- package/lib/typescript/components/holdItem/HoldItem.d.ts +1 -1
- package/lib/typescript/components/holdItem/types.d.ts +13 -15
- package/lib/typescript/components/menu/types.d.ts +7 -0
- package/lib/typescript/components/provider/Provider.d.ts +1 -1
- package/lib/typescript/components/provider/types.d.ts +1 -1
- package/lib/typescript/context/internal.d.ts +3 -4
- package/lib/typescript/index.d.ts +2 -2
- package/package.json +1 -1
- package/src/components/backdrop/Backdrop.tsx +2 -5
- package/src/components/customView/CustomView.tsx +164 -0
- package/src/components/holdItem/HoldItem.tsx +20 -25
- package/src/components/holdItem/types.d.ts +13 -15
- package/src/components/menu/Menu.tsx +4 -5
- package/src/components/menu/MenuList.tsx +23 -4
- package/src/components/menu/types.d.ts +7 -0
- package/src/components/provider/Provider.tsx +16 -18
- package/src/components/provider/types.d.ts +1 -1
- package/src/context/internal.ts +3 -8
- package/src/index.ts +5 -4
- package/lib/commonjs/components/provider/Content.js +0 -74
- package/lib/commonjs/components/provider/Content.js.map +0 -1
- package/lib/module/components/provider/Content.js +0 -59
- package/lib/module/components/provider/Content.js.map +0 -1
- package/lib/typescript/components/provider/Content.d.ts +0 -2
- 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:
|
|
42
|
-
|
|
43
|
-
|
|
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:
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
70
|
-
|
|
65
|
+
if (onOpen)
|
|
66
|
+
runOnJS(onOpen)();
|
|
67
|
+
break
|
|
71
68
|
}
|
|
72
69
|
case CONTEXT_MENU_STATE.END: {
|
|
73
|
-
if (onClose)
|
|
74
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
102
|
+
<CustomView />
|
|
105
103
|
</PortalProvider>
|
|
106
104
|
</InternalContext.Provider>
|
|
107
105
|
</GestureHandlerRootView>
|
|
108
106
|
);
|
|
109
107
|
};
|
|
110
108
|
|
|
111
|
-
const Provider = memo(ProviderComponent)
|
|
109
|
+
const Provider = memo(ProviderComponent);
|
|
112
110
|
|
|
113
111
|
export default Provider;
|
package/src/context/internal.ts
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
6
|
+
export type { HoldItemProps } from './components/holdItem/types';
|
|
7
7
|
export type {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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,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;
|