@tamagui/native 3.0.0-beta.924.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/PressBoundary.cjs +2 -48
- package/dist/cjs/PressBoundary.native.cjs +3 -3
- package/dist/cjs/PressBoundary.native.js +3 -3
- package/dist/cjs/PressBoundary.native.js.map +1 -1
- package/dist/cjs/components.cjs +6 -2
- package/dist/cjs/components.native.cjs +6 -2
- package/dist/cjs/components.native.js +6 -2
- package/dist/cjs/components.native.js.map +1 -1
- package/dist/cjs/expoUIMenuAdapter.native.cjs +1 -5
- package/dist/cjs/expoUIMenuAdapter.native.js +1 -5
- package/dist/cjs/expoUIMenuAdapter.native.js.map +1 -1
- package/dist/cjs/expoUIMenuView.cjs +82 -0
- package/dist/cjs/expoUIMenuView.native.cjs +100 -0
- package/dist/cjs/expoUIMenuView.native.js +102 -0
- package/dist/cjs/expoUIMenuView.native.js.map +1 -0
- package/dist/cjs/index.cjs +0 -2
- package/dist/cjs/index.native.cjs +0 -2
- package/dist/cjs/index.native.js +0 -2
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/nativeMenuContext.cjs +3 -1
- package/dist/cjs/nativeMenuContext.native.cjs +6 -1
- package/dist/cjs/nativeMenuContext.native.js +6 -1
- package/dist/cjs/nativeMenuContext.native.js.map +1 -1
- package/dist/cjs/setup-expo-ui-menu.cjs +6 -1
- package/dist/cjs/setup-expo-ui-menu.native.cjs +6 -1
- package/dist/cjs/setup-expo-ui-menu.native.js +6 -1
- package/dist/cjs/setup-expo-ui-menu.native.js.map +1 -1
- package/dist/cjs/setup-one-portal.cjs +23 -0
- package/dist/cjs/setup-one-portal.native.cjs +25 -0
- package/dist/cjs/setup-one-portal.native.js +27 -0
- package/dist/cjs/setup-one-portal.native.js.map +1 -0
- package/dist/esm/PressBoundary.mjs +3 -43
- package/dist/esm/PressBoundary.mjs.map +1 -1
- package/dist/esm/PressBoundary.native.js.map +1 -1
- package/dist/esm/components.mjs +6 -2
- package/dist/esm/components.mjs.map +1 -1
- package/dist/esm/components.native.js +6 -2
- package/dist/esm/components.native.js.map +1 -1
- package/dist/esm/expoUIMenuAdapter.native.js +1 -5
- package/dist/esm/expoUIMenuAdapter.native.js.map +1 -1
- package/dist/esm/expoUIMenuView.mjs +63 -0
- package/dist/esm/expoUIMenuView.mjs.map +1 -0
- package/dist/esm/expoUIMenuView.native.js +73 -0
- package/dist/esm/expoUIMenuView.native.js.map +1 -0
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.mjs +1 -2
- package/dist/esm/index.native.js +1 -2
- package/dist/esm/nativeMenuContext.mjs +3 -1
- package/dist/esm/nativeMenuContext.mjs.map +1 -1
- package/dist/esm/nativeMenuContext.native.js +6 -1
- package/dist/esm/nativeMenuContext.native.js.map +1 -1
- package/dist/esm/setup-burnt.mjs +1 -6
- package/dist/esm/setup-burnt.native.js +0 -5
- package/dist/esm/setup-expo-ui-menu.mjs +6 -6
- package/dist/esm/setup-expo-ui-menu.mjs.map +1 -1
- package/dist/esm/setup-expo-ui-menu.native.js +6 -6
- package/dist/esm/setup-expo-ui-menu.native.js.map +1 -1
- package/dist/esm/setup-gesture-handler.mjs +1 -6
- package/dist/esm/setup-gesture-handler.native.js +0 -5
- package/dist/esm/setup-keyboard-controller.native.js +0 -5
- package/dist/esm/setup-one-portal.mjs +26 -0
- package/dist/esm/setup-one-portal.mjs.map +1 -0
- package/dist/esm/setup-one-portal.native.js +26 -0
- package/dist/esm/setup-one-portal.native.js.map +1 -0
- package/dist/esm/setup-teleport.mjs +1 -6
- package/dist/esm/setup-teleport.native.js +0 -5
- package/dist/esm/setup-worklets.mjs +1 -6
- package/dist/esm/setup-worklets.native.js +0 -5
- package/dist/esm/setup-zeego.mjs +2 -7
- package/dist/esm/setup-zeego.native.js +0 -5
- package/package.json +28 -26
- package/setup-one-portal/index.cjs +2 -0
- package/setup-one-portal/index.js +2 -0
- package/setup-one-portal/index.native.cjs +2 -0
- package/setup-one-portal/index.native.js +2 -0
- package/setup-one-portal.cjs +1 -0
- package/src/PressBoundary.native.tsx +75 -0
- package/src/PressBoundary.tsx +16 -83
- package/src/components.tsx +3 -2
- package/src/expoUIMenuAdapter.tsx +2 -2
- package/src/expoUIMenuView.tsx +124 -0
- package/src/gesture-handler.ts +1 -1
- package/src/index.ts +0 -7
- package/src/nativeMenuContext.ts +7 -1
- package/src/setup-expo-ui-menu.ts +9 -1
- package/src/setup-one-portal.ts +32 -0
- package/src/types.ts +11 -5
- package/types/PressBoundary.d.ts +13 -14
- package/types/PressBoundary.d.ts.map +2 -2
- package/types/PressBoundary.native.d.ts +8 -0
- package/types/PressBoundary.native.d.ts.map +11 -0
- package/types/components.d.ts.map +1 -1
- package/types/expoUIMenuAdapter.d.ts +27 -1
- package/types/expoUIMenuAdapter.d.ts.map +2 -2
- package/types/expoUIMenuView.d.ts +24 -0
- package/types/expoUIMenuView.d.ts.map +11 -0
- package/types/gesture-handler.d.ts +1 -1
- package/types/gesture-handler.d.ts.map +1 -1
- package/types/index.d.ts +1 -5
- package/types/index.d.ts.map +2 -2
- package/types/nativeMenuContext.d.ts.map +2 -2
- package/types/setup-expo-ui-menu.d.ts.map +1 -1
- package/types/setup-one-portal.d.ts +3 -0
- package/types/setup-one-portal.d.ts.map +11 -0
- package/types/types.d.ts +10 -4
- package/types/types.d.ts.map +2 -2
- package/dist/cjs/linearGradientState.cjs +0 -41
- package/dist/cjs/linearGradientState.native.cjs +0 -43
- package/dist/cjs/linearGradientState.native.js +0 -45
- package/dist/cjs/linearGradientState.native.js.map +0 -1
- package/dist/cjs/setup-expo-linear-gradient.cjs +0 -16
- package/dist/cjs/setup-expo-linear-gradient.native.cjs +0 -18
- package/dist/cjs/setup-expo-linear-gradient.native.js +0 -20
- package/dist/cjs/setup-expo-linear-gradient.native.js.map +0 -1
- package/dist/esm/linearGradientState.mjs +0 -22
- package/dist/esm/linearGradientState.mjs.map +0 -1
- package/dist/esm/linearGradientState.native.js +0 -22
- package/dist/esm/linearGradientState.native.js.map +0 -1
- package/dist/esm/setup-expo-linear-gradient.mjs +0 -24
- package/dist/esm/setup-expo-linear-gradient.mjs.map +0 -1
- package/dist/esm/setup-expo-linear-gradient.native.js +0 -24
- package/dist/esm/setup-expo-linear-gradient.native.js.map +0 -1
- package/setup-expo-linear-gradient/index.cjs +0 -2
- package/setup-expo-linear-gradient/index.js +0 -2
- package/setup-expo-linear-gradient/index.native.cjs +0 -2
- package/setup-expo-linear-gradient/index.native.js +0 -2
- package/setup-expo-linear-gradient.cjs +0 -1
- package/src/linearGradientState.ts +0 -27
- package/src/setup-expo-linear-gradient.ts +0 -36
- package/types/linearGradientState.d.ts +0 -9
- package/types/linearGradientState.d.ts.map +0 -11
- package/types/setup-expo-linear-gradient.d.ts +0 -3
- package/types/setup-expo-linear-gradient.d.ts.map +0 -11
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/native",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"description": "Native setup modules for Tamagui - portals, gesture handler, worklets, and more",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"sideEffects": [
|
|
@@ -15,8 +16,6 @@
|
|
|
15
16
|
"gesture-handler.cjs",
|
|
16
17
|
"setup-burnt",
|
|
17
18
|
"setup-burnt.cjs",
|
|
18
|
-
"setup-expo-linear-gradient",
|
|
19
|
-
"setup-expo-linear-gradient.cjs",
|
|
20
19
|
"setup-expo-ui-menu",
|
|
21
20
|
"setup-expo-ui-menu.cjs",
|
|
22
21
|
"setup-gesture-handler",
|
|
@@ -25,6 +24,8 @@
|
|
|
25
24
|
"setup-keyboard-controller.cjs",
|
|
26
25
|
"setup-safe-area",
|
|
27
26
|
"setup-safe-area.cjs",
|
|
27
|
+
"setup-one-portal",
|
|
28
|
+
"setup-one-portal.cjs",
|
|
28
29
|
"setup-teleport",
|
|
29
30
|
"setup-teleport.cjs",
|
|
30
31
|
"setup-worklets",
|
|
@@ -37,6 +38,9 @@
|
|
|
37
38
|
"types": "./types/index.d.ts",
|
|
38
39
|
"typesVersions": {
|
|
39
40
|
"*": {
|
|
41
|
+
"setup-one-portal": [
|
|
42
|
+
"./types/setup-one-portal.d.ts"
|
|
43
|
+
],
|
|
40
44
|
"setup-teleport": [
|
|
41
45
|
"./types/setup-teleport.d.ts"
|
|
42
46
|
],
|
|
@@ -52,9 +56,6 @@
|
|
|
52
56
|
"setup-safe-area": [
|
|
53
57
|
"./types/setup-safe-area.d.ts"
|
|
54
58
|
],
|
|
55
|
-
"setup-expo-linear-gradient": [
|
|
56
|
-
"./types/setup-expo-linear-gradient.d.ts"
|
|
57
|
-
],
|
|
58
59
|
"setup-keyboard-controller": [
|
|
59
60
|
"./types/setup-keyboard-controller.d.ts"
|
|
60
61
|
],
|
|
@@ -80,6 +81,15 @@
|
|
|
80
81
|
"require": "./dist/cjs/index.cjs",
|
|
81
82
|
"default": "./dist/esm/index.mjs"
|
|
82
83
|
},
|
|
84
|
+
"./setup-one-portal": {
|
|
85
|
+
"types": "./types/setup-one-portal.d.ts",
|
|
86
|
+
"react-native": "./dist/esm/setup-one-portal.native.js",
|
|
87
|
+
"browser": "./dist/esm/setup-one-portal.mjs",
|
|
88
|
+
"module": "./dist/esm/setup-one-portal.mjs",
|
|
89
|
+
"import": "./dist/esm/setup-one-portal.mjs",
|
|
90
|
+
"require": "./dist/cjs/setup-one-portal.cjs",
|
|
91
|
+
"default": "./dist/esm/setup-one-portal.mjs"
|
|
92
|
+
},
|
|
83
93
|
"./setup-teleport": {
|
|
84
94
|
"types": "./types/setup-teleport.d.ts",
|
|
85
95
|
"react-native": "./dist/esm/setup-teleport.native.js",
|
|
@@ -125,15 +135,6 @@
|
|
|
125
135
|
"require": "./dist/cjs/setup-safe-area.cjs",
|
|
126
136
|
"default": "./dist/esm/setup-safe-area.mjs"
|
|
127
137
|
},
|
|
128
|
-
"./setup-expo-linear-gradient": {
|
|
129
|
-
"types": "./types/setup-expo-linear-gradient.d.ts",
|
|
130
|
-
"react-native": "./dist/esm/setup-expo-linear-gradient.native.js",
|
|
131
|
-
"browser": "./dist/esm/setup-expo-linear-gradient.mjs",
|
|
132
|
-
"module": "./dist/esm/setup-expo-linear-gradient.mjs",
|
|
133
|
-
"import": "./dist/esm/setup-expo-linear-gradient.mjs",
|
|
134
|
-
"require": "./dist/cjs/setup-expo-linear-gradient.cjs",
|
|
135
|
-
"default": "./dist/esm/setup-expo-linear-gradient.mjs"
|
|
136
|
-
},
|
|
137
138
|
"./setup-keyboard-controller": {
|
|
138
139
|
"types": "./types/setup-keyboard-controller.d.ts",
|
|
139
140
|
"react-native": "./dist/esm/setup-keyboard-controller.native.js",
|
|
@@ -181,18 +182,18 @@
|
|
|
181
182
|
"clean:build": "tamagui-build clean:build"
|
|
182
183
|
},
|
|
183
184
|
"dependencies": {
|
|
184
|
-
"@tamagui/compose-refs": "3.0.
|
|
185
|
+
"@tamagui/compose-refs": "3.0.1",
|
|
186
|
+
"@tamagui/react-native-types": "3.0.1"
|
|
185
187
|
},
|
|
186
188
|
"devDependencies": {
|
|
187
189
|
"@expo/ui": "~57.0.12",
|
|
188
|
-
"@tamagui/build": "3.0.
|
|
190
|
+
"@tamagui/build": "3.0.1",
|
|
189
191
|
"burnt": "^0.13.0",
|
|
190
|
-
"expo-linear-gradient": "~57.0.1",
|
|
191
192
|
"react": "19.2.3",
|
|
192
|
-
"react-native": "0.
|
|
193
|
-
"react-native-gesture-handler": "
|
|
193
|
+
"react-native": "0.87.1",
|
|
194
|
+
"react-native-gesture-handler": "3.3.0",
|
|
194
195
|
"react-native-keyboard-controller": "1.21.11",
|
|
195
|
-
"react-native-safe-area-context": "
|
|
196
|
+
"react-native-safe-area-context": "5.10.1",
|
|
196
197
|
"react-native-teleport": "^1.0.0",
|
|
197
198
|
"react-native-web": "~0.21.0",
|
|
198
199
|
"react-native-worklets-core": "^1.0.0",
|
|
@@ -201,7 +202,7 @@
|
|
|
201
202
|
"peerDependencies": {
|
|
202
203
|
"@expo/ui": "*",
|
|
203
204
|
"burnt": "*",
|
|
204
|
-
"
|
|
205
|
+
"one": "*",
|
|
205
206
|
"react": "*",
|
|
206
207
|
"react-native": "*",
|
|
207
208
|
"react-native-gesture-handler": "*",
|
|
@@ -225,9 +226,6 @@
|
|
|
225
226
|
"react-native-web": {
|
|
226
227
|
"optional": true
|
|
227
228
|
},
|
|
228
|
-
"expo-linear-gradient": {
|
|
229
|
-
"optional": true
|
|
230
|
-
},
|
|
231
229
|
"react-native-gesture-handler": {
|
|
232
230
|
"optional": true
|
|
233
231
|
},
|
|
@@ -245,11 +243,15 @@
|
|
|
245
243
|
},
|
|
246
244
|
"zeego": {
|
|
247
245
|
"optional": true
|
|
246
|
+
},
|
|
247
|
+
"one": {
|
|
248
|
+
"optional": true
|
|
248
249
|
}
|
|
249
250
|
},
|
|
250
251
|
"repository": {
|
|
251
252
|
"type": "git",
|
|
252
253
|
"url": "git+https://github.com/tamagui/tamagui.git",
|
|
253
254
|
"directory": "code/core/native"
|
|
254
|
-
}
|
|
255
|
+
},
|
|
256
|
+
"releaseSourceCommit": "c156b7cc55e5a6cc5883ebc8189720850ac32dbd"
|
|
255
257
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.assign(module.exports, require('./dist/cjs/setup-one-portal.cjs'))
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createRefComponent } from '@tamagui/compose-refs'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { View, type ViewInstance } from 'react-native'
|
|
4
|
+
import {
|
|
5
|
+
claimExternalPressOwnership,
|
|
6
|
+
releaseExternalPressOwnership,
|
|
7
|
+
type ExternalPressOwnershipToken,
|
|
8
|
+
} from './gestureState'
|
|
9
|
+
import type { PressBoundaryProps } from './types'
|
|
10
|
+
|
|
11
|
+
function composeFirst<T extends (...args: any[]) => void>(ours: T, theirs?: T) {
|
|
12
|
+
return (...args: Parameters<T>) => {
|
|
13
|
+
ours(...args)
|
|
14
|
+
theirs?.(...args)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function composeLast<T extends (...args: any[]) => void>(theirs: T | undefined, ours: T) {
|
|
19
|
+
return (...args: Parameters<T>) => {
|
|
20
|
+
theirs?.(...args)
|
|
21
|
+
ours(...args)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const PressBoundary: (
|
|
26
|
+
props: PressBoundaryProps & { ref?: React.Ref<ViewInstance> }
|
|
27
|
+
) => React.ReactNode = createRefComponent<ViewInstance, PressBoundaryProps>(
|
|
28
|
+
function PressBoundary(
|
|
29
|
+
{
|
|
30
|
+
enabled,
|
|
31
|
+
stopPropagation,
|
|
32
|
+
debugName,
|
|
33
|
+
onTouchStart,
|
|
34
|
+
onTouchEnd,
|
|
35
|
+
onTouchCancel,
|
|
36
|
+
onResponderGrant,
|
|
37
|
+
onResponderRelease,
|
|
38
|
+
onResponderTerminate,
|
|
39
|
+
...props
|
|
40
|
+
},
|
|
41
|
+
forwardedRef
|
|
42
|
+
) {
|
|
43
|
+
const tokenRef = React.useRef<ExternalPressOwnershipToken | null>(null)
|
|
44
|
+
const isEnabled = enabled ?? stopPropagation ?? true
|
|
45
|
+
|
|
46
|
+
const claim = React.useCallback((): void => {
|
|
47
|
+
if (!isEnabled) return
|
|
48
|
+
if (tokenRef.current) {
|
|
49
|
+
releaseExternalPressOwnership(tokenRef.current, debugName)
|
|
50
|
+
}
|
|
51
|
+
tokenRef.current = claimExternalPressOwnership(debugName)
|
|
52
|
+
}, [debugName, isEnabled])
|
|
53
|
+
|
|
54
|
+
const release = React.useCallback((): void => {
|
|
55
|
+
if (!tokenRef.current) return
|
|
56
|
+
releaseExternalPressOwnership(tokenRef.current, debugName)
|
|
57
|
+
tokenRef.current = null
|
|
58
|
+
}, [debugName])
|
|
59
|
+
|
|
60
|
+
React.useEffect(() => release, [release])
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<View
|
|
64
|
+
ref={forwardedRef}
|
|
65
|
+
{...props}
|
|
66
|
+
onTouchStart={composeFirst(claim, onTouchStart)}
|
|
67
|
+
onTouchEnd={composeLast(onTouchEnd, release)}
|
|
68
|
+
onTouchCancel={composeLast(onTouchCancel, release)}
|
|
69
|
+
onResponderGrant={composeFirst(claim, onResponderGrant)}
|
|
70
|
+
onResponderRelease={composeLast(onResponderRelease, release)}
|
|
71
|
+
onResponderTerminate={composeLast(onResponderTerminate, release)}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
)
|
package/src/PressBoundary.tsx
CHANGED
|
@@ -1,84 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
debugName?: string | null
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function composeFirst<T extends (...args: any[]) => void>(ours: T, theirs?: T) {
|
|
21
|
-
return (...args: Parameters<T>) => {
|
|
22
|
-
ours(...args)
|
|
23
|
-
theirs?.(...args)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function composeLast<T extends (...args: any[]) => void>(theirs: T | undefined, ours: T) {
|
|
28
|
-
return (...args: Parameters<T>) => {
|
|
29
|
-
theirs?.(...args)
|
|
30
|
-
ours(...args)
|
|
31
|
-
}
|
|
1
|
+
import type { ReactNode, Ref } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { PressBoundaryProps } from './types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Renders children as-is.
|
|
7
|
+
*
|
|
8
|
+
* The boundary exists to arbitrate Tamagui's shared press ownership with
|
|
9
|
+
* react-native-gesture-handler, which only runs on native, so on web there is
|
|
10
|
+
* nothing to claim and no view worth adding. `ref` is accepted and ignored for
|
|
11
|
+
* the same reason: there is no host node here to hand back.
|
|
12
|
+
*/
|
|
13
|
+
export function PressBoundary({
|
|
14
|
+
children,
|
|
15
|
+
}: PressBoundaryProps & { ref?: Ref<unknown> }): ReactNode {
|
|
16
|
+
return <>{children}</>
|
|
32
17
|
}
|
|
33
|
-
|
|
34
|
-
export const PressBoundary: (
|
|
35
|
-
props: PressBoundaryProps & { ref?: React.Ref<View> }
|
|
36
|
-
) => React.ReactNode = createRefComponent<View, PressBoundaryProps>(
|
|
37
|
-
function PressBoundary(
|
|
38
|
-
{
|
|
39
|
-
enabled,
|
|
40
|
-
stopPropagation,
|
|
41
|
-
debugName,
|
|
42
|
-
onTouchStart,
|
|
43
|
-
onTouchEnd,
|
|
44
|
-
onTouchCancel,
|
|
45
|
-
onResponderGrant,
|
|
46
|
-
onResponderRelease,
|
|
47
|
-
onResponderTerminate,
|
|
48
|
-
...props
|
|
49
|
-
},
|
|
50
|
-
forwardedRef
|
|
51
|
-
) {
|
|
52
|
-
const tokenRef = React.useRef<ExternalPressOwnershipToken | null>(null)
|
|
53
|
-
const isEnabled = enabled ?? stopPropagation ?? true
|
|
54
|
-
|
|
55
|
-
const claim = React.useCallback((): void => {
|
|
56
|
-
if (!isEnabled) return
|
|
57
|
-
if (tokenRef.current) {
|
|
58
|
-
releaseExternalPressOwnership(tokenRef.current, debugName)
|
|
59
|
-
}
|
|
60
|
-
tokenRef.current = claimExternalPressOwnership(debugName)
|
|
61
|
-
}, [debugName, isEnabled])
|
|
62
|
-
|
|
63
|
-
const release = React.useCallback((): void => {
|
|
64
|
-
if (!tokenRef.current) return
|
|
65
|
-
releaseExternalPressOwnership(tokenRef.current, debugName)
|
|
66
|
-
tokenRef.current = null
|
|
67
|
-
}, [debugName])
|
|
68
|
-
|
|
69
|
-
React.useEffect(() => release, [release])
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<View
|
|
73
|
-
ref={forwardedRef}
|
|
74
|
-
{...props}
|
|
75
|
-
onTouchStart={composeFirst(claim, onTouchStart)}
|
|
76
|
-
onTouchEnd={composeLast(onTouchEnd, release)}
|
|
77
|
-
onTouchCancel={composeLast(onTouchCancel, release)}
|
|
78
|
-
onResponderGrant={composeFirst(claim, onResponderGrant)}
|
|
79
|
-
onResponderRelease={composeLast(onResponderRelease, release)}
|
|
80
|
-
onResponderTerminate={composeLast(onResponderTerminate, release)}
|
|
81
|
-
/>
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
)
|
package/src/components.tsx
CHANGED
|
@@ -31,8 +31,8 @@ export function NativePortalHost({ name }: NativePortalHostProps): ReactNode {
|
|
|
31
31
|
const state = getPortal().state
|
|
32
32
|
if (state.type !== 'teleport') return null
|
|
33
33
|
|
|
34
|
-
const { PortalHost } = (globalThis as any).__tamagui_teleport
|
|
35
|
-
return <PortalHost name={name} />
|
|
34
|
+
const { PortalHost, hostStyle } = (globalThis as any).__tamagui_teleport
|
|
35
|
+
return <PortalHost name={name} style={hostStyle} />
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -44,5 +44,6 @@ export function NativePortalProvider({ children }: NativePortalProviderProps): R
|
|
|
44
44
|
if (state.type !== 'teleport') return <>{children}</>
|
|
45
45
|
|
|
46
46
|
const { PortalProvider } = (globalThis as any).__tamagui_teleport
|
|
47
|
+
if (!PortalProvider) return <>{children}</>
|
|
47
48
|
return <PortalProvider>{children}</PortalProvider>
|
|
48
49
|
}
|
|
@@ -3,7 +3,7 @@ import React from 'react'
|
|
|
3
3
|
|
|
4
4
|
import type { NativeMenuAdapter, NativeMenuModule } from './nativeMenuState'
|
|
5
5
|
|
|
6
|
-
type ExpoMenuAction = {
|
|
6
|
+
export type ExpoMenuAction = {
|
|
7
7
|
id: string
|
|
8
8
|
title: string
|
|
9
9
|
image?: unknown
|
|
@@ -17,7 +17,7 @@ type ExpoMenuAction = {
|
|
|
17
17
|
displayInline?: boolean
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
type ExpoMenuViewProps = {
|
|
20
|
+
export type ExpoMenuViewProps = {
|
|
21
21
|
actions: ExpoMenuAction[]
|
|
22
22
|
title?: string
|
|
23
23
|
shouldOpenOnLongPress?: boolean
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import type { ExpoMenuAction, ExpoMenuViewProps } from './expoUIMenuAdapter'
|
|
5
|
+
|
|
6
|
+
// the swiftui menu behind every native Menu and ContextMenu trigger on ios,
|
|
7
|
+
// composed from @expo/ui/swift-ui the same way @expo/ui's community MenuView
|
|
8
|
+
// is, minus `matchContents` on the Host. that flag copies each SwiftUI
|
|
9
|
+
// measurement back onto the host's yoga node as a fixed height, and yoga then
|
|
10
|
+
// measures the trigger's react-native children against that height, so trigger
|
|
11
|
+
// content can shrink but never grow: a row that mounts empty and fills in later
|
|
12
|
+
// stays at 0pt, and a streaming paragraph stays at its first line count. without
|
|
13
|
+
// the flag the host takes its height from the hosted react-native subtree like
|
|
14
|
+
// any other view, and RNHostView still sizes the SwiftUI side from that
|
|
15
|
+
// subtree's yoga bounds.
|
|
16
|
+
|
|
17
|
+
type SwiftUIModule = {
|
|
18
|
+
Button: ComponentType<any>
|
|
19
|
+
ContextMenu: ComponentType<any> & {
|
|
20
|
+
Trigger: ComponentType<any>
|
|
21
|
+
Items: ComponentType<any>
|
|
22
|
+
}
|
|
23
|
+
Host: ComponentType<any>
|
|
24
|
+
Menu: ComponentType<any>
|
|
25
|
+
RNHostView: ComponentType<any>
|
|
26
|
+
Section: ComponentType<any>
|
|
27
|
+
Toggle: ComponentType<any>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type SwiftUIModifiersModule = {
|
|
31
|
+
disabled: (value: boolean) => unknown
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createExpoUIMenuView({
|
|
35
|
+
swiftUI,
|
|
36
|
+
modifiers,
|
|
37
|
+
}: {
|
|
38
|
+
swiftUI: SwiftUIModule
|
|
39
|
+
modifiers: SwiftUIModifiersModule
|
|
40
|
+
}): ComponentType<ExpoMenuViewProps> {
|
|
41
|
+
const { Button, ContextMenu, Host, Menu, RNHostView, Section, Toggle } = swiftUI
|
|
42
|
+
|
|
43
|
+
function renderAction(
|
|
44
|
+
action: ExpoMenuAction,
|
|
45
|
+
onPressAction: ExpoMenuViewProps['onPressAction']
|
|
46
|
+
): ReactNode {
|
|
47
|
+
if (action.attributes?.hidden) return null
|
|
48
|
+
const { subactions, displayInline, state, attributes, image, title } = action
|
|
49
|
+
const systemImage = typeof image === 'string' ? image : undefined
|
|
50
|
+
|
|
51
|
+
if (subactions && subactions.length > 0) {
|
|
52
|
+
const children = subactions.map((sub) => renderAction(sub, onPressAction))
|
|
53
|
+
if (displayInline) {
|
|
54
|
+
return (
|
|
55
|
+
<Section key={action.id} title={title}>
|
|
56
|
+
{children}
|
|
57
|
+
</Section>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
return (
|
|
61
|
+
<Menu key={action.id} label={title} systemImage={systemImage}>
|
|
62
|
+
{children}
|
|
63
|
+
</Menu>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const fire = () => onPressAction?.({ nativeEvent: { event: action.id } })
|
|
68
|
+
const itemModifiers = attributes?.disabled ? [modifiers.disabled(true)] : undefined
|
|
69
|
+
|
|
70
|
+
if (state === 'on' || state === 'off') {
|
|
71
|
+
return (
|
|
72
|
+
<Toggle
|
|
73
|
+
key={action.id}
|
|
74
|
+
label={title}
|
|
75
|
+
systemImage={systemImage}
|
|
76
|
+
isOn={state === 'on'}
|
|
77
|
+
onIsOnChange={fire}
|
|
78
|
+
modifiers={itemModifiers}
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<Button
|
|
85
|
+
key={action.id}
|
|
86
|
+
label={title}
|
|
87
|
+
systemImage={systemImage}
|
|
88
|
+
role={attributes?.destructive ? 'destructive' : undefined}
|
|
89
|
+
modifiers={itemModifiers}
|
|
90
|
+
onPress={fire}
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return function ExpoUIMenuView({
|
|
96
|
+
actions,
|
|
97
|
+
onPressAction,
|
|
98
|
+
shouldOpenOnLongPress,
|
|
99
|
+
title,
|
|
100
|
+
children,
|
|
101
|
+
}: ExpoMenuViewProps) {
|
|
102
|
+
const items = actions.map((action) => renderAction(action, onPressAction))
|
|
103
|
+
const body = title ? <Section title={title}>{items}</Section> : items
|
|
104
|
+
// RNHostView takes exactly one element, so the trigger children ride in a
|
|
105
|
+
// fragment
|
|
106
|
+
const trigger = (
|
|
107
|
+
<RNHostView matchContents>
|
|
108
|
+
<>{children}</>
|
|
109
|
+
</RNHostView>
|
|
110
|
+
)
|
|
111
|
+
return (
|
|
112
|
+
<Host ignoreSafeArea="all">
|
|
113
|
+
{shouldOpenOnLongPress ? (
|
|
114
|
+
<ContextMenu>
|
|
115
|
+
<ContextMenu.Trigger>{trigger}</ContextMenu.Trigger>
|
|
116
|
+
<ContextMenu.Items>{body}</ContextMenu.Items>
|
|
117
|
+
</ContextMenu>
|
|
118
|
+
) : (
|
|
119
|
+
<Menu label={trigger}>{body}</Menu>
|
|
120
|
+
)}
|
|
121
|
+
</Host>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
}
|
package/src/gesture-handler.ts
CHANGED
|
@@ -10,7 +10,7 @@ export {
|
|
|
10
10
|
releaseExternalPressOwnership as unstable_releaseExternalPressOwnership,
|
|
11
11
|
} from './gestureState'
|
|
12
12
|
export { PressBoundary } from './PressBoundary'
|
|
13
|
-
export type { PressBoundaryProps } from './
|
|
13
|
+
export type { PressBoundaryProps } from './types'
|
|
14
14
|
export {
|
|
15
15
|
getGestureHandlerConfig,
|
|
16
16
|
setupGestureHandler,
|
package/src/index.ts
CHANGED
|
@@ -10,12 +10,10 @@
|
|
|
10
10
|
* import '@tamagui/native/setup-gesture-handler'
|
|
11
11
|
* import '@tamagui/native/setup-worklets'
|
|
12
12
|
* import '@tamagui/native/setup-safe-area'
|
|
13
|
-
* import '@tamagui/native/expo-linear-gradient'
|
|
14
13
|
* import '@tamagui/native/setup-keyboard-controller'
|
|
15
14
|
*
|
|
16
15
|
* // Then use Tamagui components normally
|
|
17
16
|
* // Sheet will automatically use native gestures when available
|
|
18
|
-
* // LinearGradient will use expo-linear-gradient when installed
|
|
19
17
|
* ```
|
|
20
18
|
*/
|
|
21
19
|
|
|
@@ -28,7 +26,6 @@ export type {
|
|
|
28
26
|
SafeAreaInsets,
|
|
29
27
|
SafeAreaFrame,
|
|
30
28
|
SafeAreaMetrics,
|
|
31
|
-
LinearGradientState,
|
|
32
29
|
BurntState,
|
|
33
30
|
NativePortalProps,
|
|
34
31
|
NativePortalHostProps,
|
|
@@ -64,10 +61,6 @@ export type { WorkletsAccessor } from './workletsState'
|
|
|
64
61
|
export { getSafeArea, hasSafeAreaSetup } from './safeAreaState'
|
|
65
62
|
export type { SafeAreaAccessor } from './safeAreaState'
|
|
66
63
|
|
|
67
|
-
// linear gradient
|
|
68
|
-
export { getLinearGradient } from './linearGradientState'
|
|
69
|
-
export type { LinearGradientAccessor } from './linearGradientState'
|
|
70
|
-
|
|
71
64
|
// keyboard controller state exports (safe - no side effects)
|
|
72
65
|
export {
|
|
73
66
|
isKeyboardControllerEnabled,
|
package/src/nativeMenuContext.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type React from 'react'
|
|
2
2
|
import { createContext } from 'react'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// one context per runtime: core reads it and the menu packages provide it, so a
|
|
5
|
+
// second copy of this module (a bundled core, a duplicated install) must not
|
|
6
|
+
// split them into two contexts that never see each other
|
|
7
|
+
const KEY = '__tamagui_native_menu_context__'
|
|
8
|
+
const g = globalThis as typeof globalThis & { [KEY]?: React.Context<boolean> }
|
|
9
|
+
|
|
10
|
+
export const NativeMenuContext: React.Context<boolean> = (g[KEY] ??= createContext(false))
|
|
@@ -6,12 +6,20 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { createExpoUIMenuAdapter } from './expoUIMenuAdapter'
|
|
9
|
+
import { createExpoUIMenuView } from './expoUIMenuView'
|
|
9
10
|
import { registerNativeMenuAdapter } from './nativeMenuState'
|
|
11
|
+
import { Platform } from 'react-native'
|
|
10
12
|
|
|
11
13
|
function setup(): void {
|
|
12
14
|
let MenuView
|
|
13
15
|
try {
|
|
14
|
-
MenuView =
|
|
16
|
+
MenuView =
|
|
17
|
+
Platform.OS === 'ios'
|
|
18
|
+
? createExpoUIMenuView({
|
|
19
|
+
swiftUI: require('@expo/ui/swift-ui'),
|
|
20
|
+
modifiers: require('@expo/ui/swift-ui/modifiers'),
|
|
21
|
+
})
|
|
22
|
+
: require('@expo/ui/community/menu').MenuView
|
|
15
23
|
} catch (error) {
|
|
16
24
|
if (process.env.NODE_ENV === 'development') {
|
|
17
25
|
console.warn('Error setting up Expo UI native menus', error)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup native portal support for Tamagui with One's native portals
|
|
3
|
+
* (One.UI.Portal and One.UI.PortalHost), an alternative to setup-teleport.
|
|
4
|
+
*
|
|
5
|
+
* Import this module at the top of your app entry point:
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import '@tamagui/native/setup-one-portal'
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { getPortal } from './portalState'
|
|
14
|
+
|
|
15
|
+
function setup(): void {
|
|
16
|
+
const g = globalThis as any
|
|
17
|
+
if (g.__tamagui_native_portal_setup) return
|
|
18
|
+
g.__tamagui_native_portal_setup = true
|
|
19
|
+
|
|
20
|
+
const { One } = require('one')
|
|
21
|
+
// one's portals keep their react tree without a provider and lay content out
|
|
22
|
+
// against the host's own size, so the host fills its parent.
|
|
23
|
+
g.__tamagui_teleport = {
|
|
24
|
+
Portal: One.UI.Portal,
|
|
25
|
+
PortalHost: One.UI.PortalHost,
|
|
26
|
+
hostStyle: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 },
|
|
27
|
+
}
|
|
28
|
+
getPortal().set({ enabled: true, type: 'teleport' })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// run setup immediately on import
|
|
32
|
+
setup()
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ViewProps } from '@tamagui/react-native-types'
|
|
1
2
|
import type { ReactNode } from 'react'
|
|
2
3
|
|
|
3
4
|
export type NativePortalState = {
|
|
@@ -64,11 +65,6 @@ export type NativePortalProviderProps = {
|
|
|
64
65
|
children: ReactNode
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
export interface LinearGradientState {
|
|
68
|
-
enabled: boolean
|
|
69
|
-
Component: any
|
|
70
|
-
}
|
|
71
|
-
|
|
72
68
|
export interface BurntState {
|
|
73
69
|
enabled: boolean
|
|
74
70
|
toast: ((options: any) => void) | null
|
|
@@ -85,3 +81,13 @@ export interface KeyboardControllerState {
|
|
|
85
81
|
KeyboardEvents: any
|
|
86
82
|
KeyboardStickyView: any
|
|
87
83
|
}
|
|
84
|
+
|
|
85
|
+
export interface PressBoundaryProps extends ViewProps {
|
|
86
|
+
enabled?: boolean
|
|
87
|
+
/**
|
|
88
|
+
* Alias for enabling the boundary. The behavior is limited to Tamagui's
|
|
89
|
+
* shared press ownership and does not patch arbitrary RN bubbling.
|
|
90
|
+
*/
|
|
91
|
+
stopPropagation?: boolean
|
|
92
|
+
debugName?: string | null
|
|
93
|
+
}
|
package/types/PressBoundary.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}) => React.ReactNode;
|
|
1
|
+
import type { ReactNode, Ref } from "react";
|
|
2
|
+
import type { PressBoundaryProps } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Renders children as-is.
|
|
5
|
+
*
|
|
6
|
+
* The boundary exists to arbitrate Tamagui's shared press ownership with
|
|
7
|
+
* react-native-gesture-handler, which only runs on native, so on web there is
|
|
8
|
+
* nothing to claim and no view worth adding. `ref` is accepted and ignored for
|
|
9
|
+
* the same reason: there is no host node here to hand back.
|
|
10
|
+
*/
|
|
11
|
+
export declare function PressBoundary({ children }: PressBoundaryProps & {
|
|
12
|
+
ref?: Ref<unknown>;
|
|
13
|
+
}): ReactNode;
|
|
15
14
|
|
|
16
15
|
//# sourceMappingURL=PressBoundary.d.ts.map
|