@tamagui/core 1.0.1-beta.192 → 1.0.1-beta.194
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/Tamagui.js +4 -2
- package/dist/cjs/Tamagui.js.map +2 -2
- package/dist/cjs/config.js +1 -2
- package/dist/cjs/config.js.map +2 -2
- package/dist/cjs/constants/constants.js +13 -8
- package/dist/cjs/constants/constants.js.map +2 -2
- package/dist/cjs/contexts/TextAncestorContext.js +3 -16
- package/dist/cjs/contexts/TextAncestorContext.js.map +3 -3
- package/dist/cjs/createComponent.js +196 -284
- package/dist/cjs/createComponent.js.map +2 -2
- package/dist/cjs/createTamagui.js +15 -16
- package/dist/cjs/createTamagui.js.map +3 -3
- package/dist/cjs/createVariable.js +1 -2
- package/dist/cjs/createVariable.js.map +2 -2
- package/dist/cjs/helpers/ThemeManager.js +7 -14
- package/dist/cjs/helpers/ThemeManager.js.map +2 -2
- package/dist/cjs/helpers/{createShallowUpdate.js → cache.js} +20 -21
- package/dist/cjs/helpers/cache.js.map +7 -0
- package/dist/cjs/helpers/createMediaStyle.js +14 -8
- package/dist/cjs/helpers/createMediaStyle.js.map +2 -2
- package/dist/cjs/helpers/extendStaticConfig.js +0 -1
- package/dist/cjs/helpers/extendStaticConfig.js.map +2 -2
- package/dist/cjs/helpers/getSplitStyles.js +214 -94
- package/dist/cjs/helpers/getSplitStyles.js.map +3 -3
- package/dist/cjs/helpers/getStylesAtomic.js +16 -36
- package/dist/cjs/helpers/getStylesAtomic.js.map +3 -3
- package/dist/cjs/helpers/getVariantExtras.js +2 -1
- package/dist/cjs/helpers/getVariantExtras.js.map +2 -2
- package/dist/cjs/helpers/insertStyleRule.js +14 -6
- package/dist/cjs/helpers/insertStyleRule.js.map +2 -2
- package/dist/cjs/helpers/matchMedia.js.map +2 -2
- package/dist/cjs/helpers/mergeTransform.js.map +1 -1
- package/dist/cjs/helpers/normalizeValueWithProperty.js +32 -2
- package/dist/cjs/helpers/normalizeValueWithProperty.js.map +2 -2
- package/dist/cjs/helpers/proxyThemeVariables.js +2 -7
- package/dist/cjs/helpers/proxyThemeVariables.js.map +2 -2
- package/dist/cjs/helpers/useShallowSetState.js.map +2 -2
- package/dist/cjs/hooks/getThemeUnwrapped.js +1 -3
- package/dist/cjs/hooks/getThemeUnwrapped.js.map +2 -2
- package/dist/cjs/hooks/useElementLayout.js +92 -0
- package/dist/cjs/hooks/useElementLayout.js.map +7 -0
- package/dist/cjs/hooks/useIsTouchDevice.js +2 -10
- package/dist/cjs/hooks/useIsTouchDevice.js.map +2 -2
- package/dist/cjs/hooks/useMedia.js +79 -85
- package/dist/cjs/hooks/useMedia.js.map +2 -2
- package/dist/cjs/hooks/useMedia.test.js +2 -0
- package/dist/cjs/{helpers/validate.js.map → hooks/useMedia.test.js.map} +0 -0
- package/dist/cjs/hooks/usePressablePressResponder.js +370 -0
- package/dist/cjs/hooks/usePressablePressResponder.js.map +7 -0
- package/dist/cjs/hooks/useSafeRef.js +13 -15
- package/dist/cjs/hooks/useSafeRef.js.map +2 -2
- package/dist/cjs/hooks/useTheme.js +5 -5
- package/dist/cjs/hooks/useTheme.js.map +2 -2
- package/dist/cjs/index.js +1 -17
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/static.js +0 -20
- package/dist/cjs/static.js.map +2 -2
- package/dist/cjs/styled.js +4 -22
- package/dist/cjs/styled.js.map +2 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/{hooks/useIsSSR.js → views/AbsoluteFill.js} +18 -23
- package/dist/cjs/views/AbsoluteFill.js.map +7 -0
- package/dist/cjs/views/AbsoluteFill.native.js +45 -0
- package/dist/cjs/views/AbsoluteFill.native.js.map +7 -0
- package/dist/cjs/views/FontLanguage.native.js.map +2 -2
- package/dist/cjs/views/Stack.js.map +1 -1
- package/dist/cjs/views/TamaguiProvider.js +3 -2
- package/dist/cjs/views/TamaguiProvider.js.map +2 -2
- package/dist/cjs/views/Text.js.map +1 -1
- package/dist/cjs/views/ThemeReset.js +10 -10
- package/dist/cjs/views/ThemeReset.js.map +2 -2
- package/dist/esm/Tamagui.js +4 -2
- package/dist/esm/Tamagui.js.map +2 -2
- package/dist/esm/config.js +1 -2
- package/dist/esm/config.js.map +2 -2
- package/dist/esm/constants/constants.js +11 -7
- package/dist/esm/constants/constants.js.map +2 -2
- package/dist/esm/contexts/TextAncestorContext.js +2 -13
- package/dist/esm/contexts/TextAncestorContext.js.map +2 -2
- package/dist/esm/createComponent.js +195 -286
- package/dist/esm/createComponent.js.map +2 -2
- package/dist/esm/createTamagui.js +15 -16
- package/dist/esm/createTamagui.js.map +3 -3
- package/dist/esm/createVariable.js +1 -2
- package/dist/esm/createVariable.js.map +2 -2
- package/dist/esm/helpers/ThemeManager.js +7 -14
- package/dist/esm/helpers/ThemeManager.js.map +2 -2
- package/dist/esm/helpers/cache.js +18 -0
- package/dist/esm/helpers/cache.js.map +7 -0
- package/dist/esm/helpers/createMediaStyle.js +14 -8
- package/dist/esm/helpers/createMediaStyle.js.map +2 -2
- package/dist/esm/helpers/extendStaticConfig.js +0 -1
- package/dist/esm/helpers/extendStaticConfig.js.map +2 -2
- package/dist/esm/helpers/getSplitStyles.js +223 -95
- package/dist/esm/helpers/getSplitStyles.js.map +3 -3
- package/dist/esm/helpers/getStylesAtomic.js +13 -26
- package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
- package/dist/esm/helpers/getVariantExtras.js +2 -1
- package/dist/esm/helpers/getVariantExtras.js.map +2 -2
- package/dist/esm/helpers/insertStyleRule.js +14 -6
- package/dist/esm/helpers/insertStyleRule.js.map +2 -2
- package/dist/esm/helpers/matchMedia.js.map +2 -2
- package/dist/esm/helpers/mergeTransform.js.map +1 -1
- package/dist/esm/helpers/normalizeValueWithProperty.js +30 -1
- package/dist/esm/helpers/normalizeValueWithProperty.js.map +2 -2
- package/dist/esm/helpers/proxyThemeVariables.js +2 -7
- package/dist/esm/helpers/proxyThemeVariables.js.map +2 -2
- package/dist/esm/helpers/useShallowSetState.js.map +2 -2
- package/dist/esm/hooks/getThemeUnwrapped.js +1 -3
- package/dist/esm/hooks/getThemeUnwrapped.js.map +2 -2
- package/dist/esm/hooks/useElementLayout.js +66 -0
- package/dist/esm/hooks/useElementLayout.js.map +7 -0
- package/dist/esm/hooks/useIsTouchDevice.js +3 -11
- package/dist/esm/hooks/useIsTouchDevice.js.map +2 -2
- package/dist/esm/hooks/useMedia.js +76 -84
- package/dist/esm/hooks/useMedia.js.map +2 -2
- package/dist/esm/hooks/useMedia.test.js +1 -0
- package/dist/esm/{helpers/validate.js.map → hooks/useMedia.test.js.map} +0 -0
- package/dist/esm/hooks/usePressablePressResponder.js +346 -0
- package/dist/esm/hooks/usePressablePressResponder.js.map +7 -0
- package/dist/esm/hooks/useSafeRef.js +13 -15
- package/dist/esm/hooks/useSafeRef.js.map +2 -2
- package/dist/esm/hooks/useTheme.js +5 -5
- package/dist/esm/hooks/useTheme.js.map +2 -2
- package/dist/esm/index.js +1 -14
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/static.js +0 -14
- package/dist/esm/static.js.map +2 -2
- package/dist/esm/styled.js +4 -22
- package/dist/esm/styled.js.map +2 -2
- package/dist/esm/views/AbsoluteFill.js +17 -0
- package/dist/esm/views/AbsoluteFill.js.map +7 -0
- package/dist/esm/views/AbsoluteFill.native.js +21 -0
- package/dist/esm/views/AbsoluteFill.native.js.map +7 -0
- package/dist/esm/views/FontLanguage.native.js.map +2 -2
- package/dist/esm/views/Stack.js.map +1 -1
- package/dist/esm/views/TamaguiProvider.js +5 -4
- package/dist/esm/views/TamaguiProvider.js.map +2 -2
- package/dist/esm/views/Text.js.map +1 -1
- package/dist/esm/views/ThemeReset.js +10 -10
- package/dist/esm/views/ThemeReset.js.map +2 -2
- package/package.json +14 -14
- package/src/Tamagui.ts +7 -3
- package/src/config.ts +2 -3
- package/src/constants/constants.ts +10 -6
- package/src/contexts/TextAncestorContext.tsx +1 -8
- package/src/createComponent.tsx +250 -412
- package/src/createTamagui.ts +16 -19
- package/src/createVariable.ts +1 -3
- package/src/helpers/ThemeManager.tsx +7 -15
- package/src/helpers/cache.ts +18 -0
- package/src/helpers/createMediaStyle.ts +16 -9
- package/src/helpers/createProxy.ts +16 -0
- package/src/helpers/extendStaticConfig.ts +0 -1
- package/src/helpers/getSplitStyles.tsx +259 -152
- package/src/helpers/getStylesAtomic.ts +14 -34
- package/src/helpers/getVariantExtras.tsx +2 -1
- package/src/helpers/insertStyleRule.tsx +16 -8
- package/src/helpers/matchMedia.ts +1 -0
- package/src/helpers/mergeTransform.ts +1 -1
- package/src/helpers/normalizeValueWithProperty.ts +30 -0
- package/src/helpers/proxyThemeVariables.tsx +3 -8
- package/src/helpers/useShallowSetState.tsx +0 -1
- package/src/hooks/getThemeUnwrapped.tsx +1 -2
- package/src/hooks/useElementLayout.tsx +90 -0
- package/src/hooks/useIsTouchDevice.tsx +3 -17
- package/src/hooks/useMedia.tsx +82 -88
- package/src/hooks/useSafeRef.ts +17 -18
- package/src/hooks/useTheme.tsx +6 -5
- package/src/index.ts +1 -11
- package/src/static.ts +0 -10
- package/src/styled.tsx +15 -33
- package/src/types.tsx +58 -55
- package/src/views/FontLanguage.native.tsx +1 -0
- package/src/views/Stack.tsx +1 -1
- package/src/views/TamaguiProvider.tsx +5 -5
- package/src/views/Text.tsx +1 -1
- package/src/views/ThemeReset.tsx +11 -11
- package/types/Tamagui.d.ts +6 -4
- package/types/constants/constants.d.ts +14 -3
- package/types/contexts/TextAncestorContext.d.ts +1 -3
- package/types/createComponent.d.ts +0 -15
- package/types/helpers/ThemeManager.d.ts +2 -3
- package/types/helpers/cache.d.ts +12 -0
- package/types/helpers/calc.d.ts +0 -16
- package/types/helpers/createMediaStyle.d.ts +1 -1
- package/types/helpers/createProxy.d.ts +2 -0
- package/types/helpers/getSplitStyles.d.ts +6 -10
- package/types/helpers/getStylesAtomic.d.ts +1 -5
- package/types/helpers/insertStyleRule.d.ts +2 -2
- package/types/helpers/mergeTransform.d.ts +1 -1
- package/types/helpers/normalizeValueWithProperty.d.ts +1 -0
- package/types/hooks/useElementLayout.d.ts +27 -0
- package/types/hooks/useMedia.d.ts +3 -1
- package/types/hooks/useMedia.test.d.ts +1 -0
- package/types/hooks/usePressablePressResponder.d.ts +84 -0
- package/types/index.d.ts +1 -11
- package/types/static.d.ts +0 -1
- package/types/types.d.ts +42 -44
- package/types/views/AbsoluteFill.d.ts +5 -0
- package/types/views/AbsoluteFill.native.d.ts +3 -0
- package/types/views/Stack.d.ts +1 -1
- package/types/views/Text.d.ts +1 -1
- package/dist/cjs/constants/platform.js +0 -74
- package/dist/cjs/constants/platform.js.map +0 -7
- package/dist/cjs/constants/platform.native.js +0 -62
- package/dist/cjs/constants/platform.native.js.map +0 -7
- package/dist/cjs/helpers/createShallowUpdate.js.map +0 -7
- package/dist/cjs/helpers/validate.js +0 -2
- package/dist/cjs/hooks/useDidFinishSSR.js +0 -60
- package/dist/cjs/hooks/useDidFinishSSR.js.map +0 -7
- package/dist/cjs/hooks/useIsSSR.js.map +0 -7
- package/dist/esm/constants/platform.js +0 -39
- package/dist/esm/constants/platform.js.map +0 -7
- package/dist/esm/constants/platform.native.js +0 -28
- package/dist/esm/constants/platform.native.js.map +0 -7
- package/dist/esm/helpers/createShallowUpdate.js +0 -20
- package/dist/esm/helpers/createShallowUpdate.js.map +0 -7
- package/dist/esm/helpers/validate.js +0 -1
- package/dist/esm/hooks/useDidFinishSSR.js +0 -35
- package/dist/esm/hooks/useDidFinishSSR.js.map +0 -7
- package/dist/esm/hooks/useIsSSR.js +0 -22
- package/dist/esm/hooks/useIsSSR.js.map +0 -7
- package/src/helpers/assignNativePropsToWeb.tsx +0 -178
- package/src/helpers/calc.ts +0 -68
- package/src/helpers/getFont.tsx +0 -43
- package/src/helpers/getStackSize.ts +0 -22
- package/src/helpers/startTransition.ts +0 -4
- package/src/hooks/useConstant.tsx +0 -19
- package/src/hooks/useIsMounted.ts +0 -16
- package/src/hooks/usePressable.tsx +0 -9
- package/src/hooks/useUnmountEffect.ts +0 -5
package/src/createComponent.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useComposedRefs } from '@tamagui/compose-refs'
|
|
1
2
|
import { isClient, isRSC, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
|
|
2
3
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
4
|
import {
|
|
@@ -6,16 +7,13 @@ import {
|
|
|
6
7
|
validPseudoKeys,
|
|
7
8
|
validStyles,
|
|
8
9
|
} from '@tamagui/helpers'
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
useMergeRefs,
|
|
12
|
-
usePlatformMethods,
|
|
13
|
-
useResponderEvents,
|
|
14
|
-
} from '@tamagui/rnw'
|
|
10
|
+
import { useResponderEvents } from '@tamagui/react-native-use-responder-events'
|
|
11
|
+
import type { ViewStyle } from '@tamagui/types-react-native'
|
|
15
12
|
import { useForceUpdate } from '@tamagui/use-force-update'
|
|
16
13
|
import React, {
|
|
17
14
|
Children,
|
|
18
15
|
Fragment,
|
|
16
|
+
RefObject,
|
|
19
17
|
createElement,
|
|
20
18
|
forwardRef,
|
|
21
19
|
memo,
|
|
@@ -23,13 +21,11 @@ import React, {
|
|
|
23
21
|
useContext,
|
|
24
22
|
useEffect,
|
|
25
23
|
} from 'react'
|
|
26
|
-
import { Text, View, ViewStyle } from 'react-native'
|
|
27
24
|
|
|
28
|
-
import {
|
|
25
|
+
import { onConfiguredOnce } from './config'
|
|
29
26
|
import { stackDefaultStyles } from './constants/constants'
|
|
30
27
|
import { FontLanguageContext } from './contexts/FontLanguageContext'
|
|
31
28
|
import { TextAncestorContext } from './contexts/TextAncestorContext'
|
|
32
|
-
import { assignNativePropsToWeb } from './helpers/assignNativePropsToWeb'
|
|
33
29
|
import { getReturnVariablesAs } from './helpers/createPropMapper'
|
|
34
30
|
import { extendStaticConfig, parseStaticConfig } from './helpers/extendStaticConfig'
|
|
35
31
|
import {
|
|
@@ -42,8 +38,8 @@ import { getAllSelectors } from './helpers/insertStyleRule'
|
|
|
42
38
|
import { mergeProps } from './helpers/mergeProps'
|
|
43
39
|
import { proxyThemeVariables } from './helpers/proxyThemeVariables'
|
|
44
40
|
import { useShallowSetState } from './helpers/useShallowSetState'
|
|
41
|
+
import { getRect, measureLayout, useElementLayout } from './hooks/useElementLayout'
|
|
45
42
|
import { addMediaQueryListener, getInitialMediaState } from './hooks/useMedia'
|
|
46
|
-
import { usePressable } from './hooks/usePressable'
|
|
47
43
|
import { useServerRef, useServerState } from './hooks/useServerHooks'
|
|
48
44
|
import { getThemeManager, useTheme } from './hooks/useTheme'
|
|
49
45
|
import {
|
|
@@ -63,11 +59,20 @@ import {
|
|
|
63
59
|
} from './types'
|
|
64
60
|
import { usePressability } from './vendor/Pressability'
|
|
65
61
|
import { Slot, mergeEvent } from './views/Slot'
|
|
62
|
+
import { Stack } from './views/Stack'
|
|
66
63
|
import { wrapThemeManagerContext } from './views/Theme'
|
|
67
64
|
|
|
68
65
|
React['keep']
|
|
69
66
|
|
|
67
|
+
/**
|
|
68
|
+
* All things that need one-time setup after createTamagui is called
|
|
69
|
+
*/
|
|
70
70
|
let defaultComponentState: TamaguiComponentState | null = null
|
|
71
|
+
let defaultComponentStateMounted: TamaguiComponentState | null = null
|
|
72
|
+
let tamaguiConfig: TamaguiInternalConfig
|
|
73
|
+
let AnimatedText: any
|
|
74
|
+
let AnimatedView: any
|
|
75
|
+
let initialTheme: any
|
|
71
76
|
|
|
72
77
|
export const mouseUps = new Set<Function>()
|
|
73
78
|
if (typeof document !== 'undefined') {
|
|
@@ -88,8 +93,17 @@ function mergeShorthands({ defaultProps }: StaticConfigParsed, { shorthands }: T
|
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Only on native do we need the actual underlying View/Text
|
|
98
|
+
* On the web we avoid react-native altogether in core.
|
|
99
|
+
*/
|
|
100
|
+
let BaseText: any
|
|
101
|
+
let BaseView: any
|
|
102
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
103
|
+
const native = require('react-native')
|
|
104
|
+
BaseText = native.Text || native.default.Text
|
|
105
|
+
BaseView = native.View || native.default.View
|
|
106
|
+
}
|
|
93
107
|
|
|
94
108
|
export function createComponent<
|
|
95
109
|
ComponentPropTypes extends Object = {},
|
|
@@ -106,10 +120,7 @@ export function createComponent<
|
|
|
106
120
|
})()
|
|
107
121
|
|
|
108
122
|
const defaultComponentClassName = `is_${staticConfig.componentName}`
|
|
109
|
-
|
|
110
|
-
let AnimatedText: any
|
|
111
|
-
let AnimatedView: any
|
|
112
|
-
let avoidClassesWhileAnimating = true
|
|
123
|
+
const avoidClassesWhileAnimating = true
|
|
113
124
|
let defaultNativeStyle: any
|
|
114
125
|
let tamaguiDefaultProps: any
|
|
115
126
|
let initialSplitStyles: SplitStyleResult
|
|
@@ -126,7 +137,6 @@ export function createComponent<
|
|
|
126
137
|
}
|
|
127
138
|
|
|
128
139
|
const debugProp = props['debug']
|
|
129
|
-
|
|
130
140
|
const { Component, isText, isZStack } = staticConfig
|
|
131
141
|
const componentName = props.componentName || staticConfig.componentName
|
|
132
142
|
const componentClassName = props.asChild
|
|
@@ -136,14 +146,39 @@ export function createComponent<
|
|
|
136
146
|
: defaultComponentClassName
|
|
137
147
|
|
|
138
148
|
const forceUpdate = useForceUpdate()
|
|
139
|
-
config = config || getConfig()
|
|
140
149
|
const theme = useTheme(props.theme, componentName, props, forceUpdate)
|
|
141
150
|
|
|
142
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Component state for tracking animations, pseudos
|
|
153
|
+
*/
|
|
154
|
+
const hasEnterStyle = !!props.enterStyle
|
|
155
|
+
const needsMount = Boolean((isWeb ? isClient : true) && (hasEnterStyle || props.animation))
|
|
156
|
+
const states = useServerState<TamaguiComponentState>(
|
|
157
|
+
needsMount ? defaultComponentState! : defaultComponentStateMounted!
|
|
158
|
+
)
|
|
159
|
+
|
|
143
160
|
const state = propsIn.forceStyle ? { ...states[0], [propsIn.forceStyle]: true } : states[0]
|
|
161
|
+
const setState = states[1]
|
|
162
|
+
const setStateShallow = useShallowSetState(setState)
|
|
163
|
+
|
|
164
|
+
const shouldSetMounted = needsMount && !state.mounted
|
|
165
|
+
const setMounted = shouldSetMounted
|
|
166
|
+
? () => {
|
|
167
|
+
// for some reason without some small delay it doesn't animate css
|
|
168
|
+
setTimeout(
|
|
169
|
+
() => {
|
|
170
|
+
setStateShallow({
|
|
171
|
+
mounted: true,
|
|
172
|
+
})
|
|
173
|
+
},
|
|
174
|
+
isWeb ? 10 : 0
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
: undefined
|
|
144
178
|
|
|
145
179
|
const shouldAvoidClasses =
|
|
146
180
|
!!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
|
|
181
|
+
|
|
147
182
|
const shouldForcePseudo = !!propsIn.forceStyle
|
|
148
183
|
const hasTextAncestor = !!(isWeb && isText ? useContext(TextAncestorContext) : false)
|
|
149
184
|
const splitStyleState =
|
|
@@ -163,19 +198,45 @@ export function createComponent<
|
|
|
163
198
|
|
|
164
199
|
const languageContext = isRSC ? null : useContext(FontLanguageContext)
|
|
165
200
|
|
|
201
|
+
const useAnimations = tamaguiConfig.animations?.useAnimations as UseAnimationHook | undefined
|
|
202
|
+
const nextIsAnimated = !!(useAnimations && props.animation)
|
|
203
|
+
// conditional but if ever true stays true
|
|
204
|
+
const isAnimated = nextIsAnimated || state.hasAnimation
|
|
205
|
+
if (nextIsAnimated && !state.hasAnimation) {
|
|
206
|
+
setStateShallow({ hasAnimation: true })
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const isTaggable = !Component || typeof Component === 'string'
|
|
210
|
+
// default to tag, fallback to component (when both strings)
|
|
211
|
+
const element = isWeb ? (isTaggable ? props.tag || Component : Component) : Component
|
|
212
|
+
|
|
213
|
+
const BaseTextComponent = BaseText || element || 'span'
|
|
214
|
+
const BaseViewComponent = BaseView || element || (hasTextAncestor ? 'span' : 'div')
|
|
215
|
+
let elementType = isText
|
|
216
|
+
? (isAnimated ? AnimatedText : null) || BaseTextComponent
|
|
217
|
+
: (isAnimated ? AnimatedView : null) || BaseViewComponent
|
|
218
|
+
|
|
219
|
+
elementType = Component || elementType
|
|
220
|
+
const isStringElement = typeof elementType === 'string'
|
|
221
|
+
|
|
166
222
|
const splitStyles = useSplitStyles(
|
|
167
223
|
props,
|
|
168
224
|
staticConfig,
|
|
169
225
|
theme,
|
|
170
226
|
splitStyleState,
|
|
171
|
-
props.asChild ? null : initialSplitStyles
|
|
227
|
+
props.asChild ? null : initialSplitStyles,
|
|
172
228
|
languageContext || undefined,
|
|
229
|
+
elementType,
|
|
173
230
|
debugProp
|
|
174
231
|
)
|
|
175
232
|
|
|
176
233
|
const hostRef = useServerRef<TamaguiElement>(null)
|
|
177
|
-
|
|
178
|
-
|
|
234
|
+
|
|
235
|
+
// animation setup
|
|
236
|
+
const isReactNativeWeb = Boolean(
|
|
237
|
+
staticConfig.isReactNativeWeb || (isAnimated && tamaguiConfig.animations.isReactNativeWeb)
|
|
238
|
+
)
|
|
239
|
+
const isAnimatedReactNativeWeb = isAnimated && avoidClassesWhileAnimating
|
|
179
240
|
|
|
180
241
|
if (process.env.NODE_ENV === 'development') {
|
|
181
242
|
if (!process.env.TAMAGUI_TARGET) {
|
|
@@ -187,7 +248,7 @@ export function createComponent<
|
|
|
187
248
|
const name = `${
|
|
188
249
|
componentName || Component?.displayName || Component?.name || '[Unnamed Component]'
|
|
189
250
|
}`
|
|
190
|
-
const type =
|
|
251
|
+
const type = isReactNativeWeb ? 'rnw' : 'tamagui'
|
|
191
252
|
const banner = `${name} ${propsIn['data-is'] || ''} ${type}`
|
|
192
253
|
// eslint-disable-next-line no-console
|
|
193
254
|
console.group(`%c 🐛 ${banner}`, 'background: yellow;')
|
|
@@ -221,55 +282,16 @@ export function createComponent<
|
|
|
221
282
|
mediaKeys,
|
|
222
283
|
} = splitStyles
|
|
223
284
|
|
|
224
|
-
// media queries
|
|
225
|
-
useIsomorphicLayoutEffect(() => {
|
|
226
|
-
if (!mediaKeys.length) {
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
const disposers: any[] = []
|
|
230
|
-
for (const key of mediaKeys) {
|
|
231
|
-
disposers.push(
|
|
232
|
-
addMediaQueryListener(key, (next: boolean) => {
|
|
233
|
-
setState((prev) => {
|
|
234
|
-
if (prev.mediaState![key] !== next) {
|
|
235
|
-
return {
|
|
236
|
-
...prev,
|
|
237
|
-
mediaState: {
|
|
238
|
-
...prev.mediaState,
|
|
239
|
-
[key]: next,
|
|
240
|
-
},
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return prev
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
)
|
|
247
|
-
}
|
|
248
|
-
return () => {}
|
|
249
|
-
}, [mediaKeys.join(',')])
|
|
250
|
-
|
|
251
|
-
// animations
|
|
252
|
-
const useAnimations = tamaguiConfig?.animations?.useAnimations as UseAnimationHook | undefined
|
|
253
|
-
|
|
254
|
-
const nextIsAnimated = !!(useAnimations && props.animation)
|
|
255
|
-
// conditional but if ever true stays true
|
|
256
|
-
const isAnimated = nextIsAnimated || state.hasAnimation
|
|
257
|
-
if (nextIsAnimated && !state.hasAnimation) {
|
|
258
|
-
setStateShallow({ hasAnimation: true })
|
|
259
|
-
}
|
|
260
|
-
|
|
261
285
|
const animationFeatureStylesIn = props.animation
|
|
262
286
|
? { ...defaultNativeStyle, ...splitStylesStyle }
|
|
263
287
|
: null
|
|
264
288
|
const propsWithAnimation = props as UseAnimationProps
|
|
265
289
|
|
|
266
|
-
//
|
|
267
|
-
// reason is animations are heavy no way around it, and must be run inline here (🙅 loading as a sub-component)
|
|
268
|
-
|
|
269
|
-
// so requiring key change on animation change is least-bad option.
|
|
270
|
-
// plus, React use() may let us get away with conditional hooks soon :)
|
|
290
|
+
// once you set animation prop don't remove it, you can set to undefined/false
|
|
291
|
+
// reason is animations are heavy - no way around it, and must be run inline here (🙅 loading as a sub-component)
|
|
292
|
+
let animationStyles: any
|
|
271
293
|
if (!isRSC && isAnimated && useAnimations) {
|
|
272
|
-
const
|
|
294
|
+
const animations = useAnimations(propsWithAnimation, {
|
|
273
295
|
state,
|
|
274
296
|
pseudos,
|
|
275
297
|
onDidAnimate: props.onDidAnimate,
|
|
@@ -321,7 +343,6 @@ export function createComponent<
|
|
|
321
343
|
// enterStyle,
|
|
322
344
|
pseudos.hoverStyle,
|
|
323
345
|
pseudos.focusStyle,
|
|
324
|
-
pseudos.pressStyle,
|
|
325
346
|
pseudos.pressStyle
|
|
326
347
|
)
|
|
327
348
|
|
|
@@ -332,7 +353,7 @@ export function createComponent<
|
|
|
332
353
|
exitStyle && isExiting && merge(style, exitStyle)
|
|
333
354
|
|
|
334
355
|
if (process.env.NODE_ENV === 'development') {
|
|
335
|
-
if (debugProp) {
|
|
356
|
+
if (debugProp === 'verbose') {
|
|
336
357
|
// eslint-disable-next-line no-console
|
|
337
358
|
console.log('animation style', style)
|
|
338
359
|
}
|
|
@@ -343,16 +364,41 @@ export function createComponent<
|
|
|
343
364
|
//, delay
|
|
344
365
|
})
|
|
345
366
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
setStateShallow({
|
|
349
|
-
animation: animationState,
|
|
350
|
-
})
|
|
367
|
+
if (animations) {
|
|
368
|
+
animationStyles = animations.style
|
|
351
369
|
}
|
|
352
370
|
}
|
|
353
371
|
|
|
372
|
+
// media queries
|
|
373
|
+
useIsomorphicLayoutEffect(() => {
|
|
374
|
+
if (!mediaKeys.length) return
|
|
375
|
+
const disposers: any[] = []
|
|
376
|
+
for (const key of mediaKeys) {
|
|
377
|
+
disposers.push(
|
|
378
|
+
addMediaQueryListener(key, (next: boolean) => {
|
|
379
|
+
setState((prev) => {
|
|
380
|
+
if (prev.mediaState![key] !== next) {
|
|
381
|
+
return {
|
|
382
|
+
...prev,
|
|
383
|
+
mediaState: {
|
|
384
|
+
...prev.mediaState,
|
|
385
|
+
[key]: next,
|
|
386
|
+
},
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return prev
|
|
390
|
+
})
|
|
391
|
+
})
|
|
392
|
+
)
|
|
393
|
+
}
|
|
394
|
+
return () => {
|
|
395
|
+
for (const disposer of disposers) {
|
|
396
|
+
disposer()
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}, [mediaKeys.join(',')])
|
|
400
|
+
|
|
354
401
|
const {
|
|
355
|
-
tag,
|
|
356
402
|
hitSlop,
|
|
357
403
|
asChild,
|
|
358
404
|
children,
|
|
@@ -382,20 +428,6 @@ export function createComponent<
|
|
|
382
428
|
...nonTamaguiProps
|
|
383
429
|
} = viewPropsIn
|
|
384
430
|
|
|
385
|
-
// get the right component
|
|
386
|
-
const isTaggable = !Component || typeof Component === 'string'
|
|
387
|
-
|
|
388
|
-
// default to tag, fallback to component (when both strings)
|
|
389
|
-
const element = isWeb ? (isTaggable ? tag || Component : Component) : Component
|
|
390
|
-
const BaseTextComponent = !isWeb ? Text : element || 'span'
|
|
391
|
-
const BaseViewComponent = !isWeb ? View : element || (hasTextAncestor ? 'span' : 'div')
|
|
392
|
-
let elementType = isText
|
|
393
|
-
? (isAnimated ? AnimatedText || Text : null) || BaseTextComponent
|
|
394
|
-
: (isAnimated ? AnimatedView || View : null) || BaseViewComponent
|
|
395
|
-
|
|
396
|
-
elementType = Component || elementType
|
|
397
|
-
const isStringElement = typeof elementType === 'string'
|
|
398
|
-
|
|
399
431
|
const disabled =
|
|
400
432
|
(props.accessibilityState != null && props.accessibilityState.disabled === true) ||
|
|
401
433
|
props.accessibilityDisabled
|
|
@@ -404,26 +436,8 @@ export function createComponent<
|
|
|
404
436
|
// so the type is pretty loose
|
|
405
437
|
let viewProps: Record<string, any>
|
|
406
438
|
|
|
407
|
-
const hasEnterStyle = !!props.enterStyle
|
|
408
|
-
const shouldSetMounted = Boolean(
|
|
409
|
-
(isWeb ? isClient : true) && (hasEnterStyle || props.animation) && !state.mounted
|
|
410
|
-
)
|
|
411
|
-
const setMounted = shouldSetMounted
|
|
412
|
-
? () => {
|
|
413
|
-
// for some reason without some small delay it doesn't animate css
|
|
414
|
-
setTimeout(
|
|
415
|
-
() => {
|
|
416
|
-
setStateShallow({
|
|
417
|
-
mounted: true,
|
|
418
|
-
})
|
|
419
|
-
},
|
|
420
|
-
isWeb ? 10 : 0
|
|
421
|
-
)
|
|
422
|
-
}
|
|
423
|
-
: undefined
|
|
424
|
-
|
|
425
439
|
// if react-native-web view just pass all props down
|
|
426
|
-
if (process.env.TAMAGUI_TARGET === 'web' && !
|
|
440
|
+
if (process.env.TAMAGUI_TARGET === 'web' && !isReactNativeWeb) {
|
|
427
441
|
// otherwise replicate react-native-web functionality
|
|
428
442
|
const {
|
|
429
443
|
// event props
|
|
@@ -444,112 +458,14 @@ export function createComponent<
|
|
|
444
458
|
onStartShouldSetResponder,
|
|
445
459
|
onStartShouldSetResponderCapture,
|
|
446
460
|
|
|
447
|
-
// react-native props
|
|
448
|
-
nativeID,
|
|
449
|
-
|
|
450
|
-
// react-native-web accessibility props
|
|
451
|
-
// @ts-ignore
|
|
452
|
-
accessibilityActiveDescendant,
|
|
453
|
-
// @ts-ignore
|
|
454
|
-
accessibilityAtomic,
|
|
455
|
-
// @ts-ignore
|
|
456
|
-
accessibilityAutoComplete,
|
|
457
|
-
// @ts-ignore
|
|
458
|
-
accessibilityBusy,
|
|
459
|
-
// @ts-ignore
|
|
460
|
-
accessibilityChecked,
|
|
461
|
-
// @ts-ignore
|
|
462
|
-
accessibilityColumnCount,
|
|
463
|
-
// @ts-ignore
|
|
464
|
-
accessibilityColumnIndex,
|
|
465
|
-
// @ts-ignore
|
|
466
|
-
accessibilityColumnSpan,
|
|
467
|
-
// @ts-ignore
|
|
468
|
-
accessibilityControls,
|
|
469
|
-
// @ts-ignore
|
|
470
|
-
accessibilityCurrent,
|
|
471
|
-
// @ts-ignore
|
|
472
|
-
accessibilityDescribedBy,
|
|
473
|
-
// @ts-ignore
|
|
474
|
-
accessibilityDetails,
|
|
475
|
-
// @ts-ignore
|
|
476
|
-
accessibilityDisabled,
|
|
477
|
-
// @ts-ignore
|
|
478
|
-
accessibilityErrorMessage,
|
|
479
|
-
// @ts-ignore
|
|
480
|
-
accessibilityExpanded,
|
|
481
|
-
// @ts-ignore
|
|
482
|
-
accessibilityFlowTo,
|
|
483
|
-
// @ts-ignore
|
|
484
|
-
accessibilityHasPopup,
|
|
485
|
-
// @ts-ignore
|
|
486
|
-
accessibilityHidden,
|
|
487
|
-
// @ts-ignore
|
|
488
|
-
accessibilityInvalid,
|
|
489
|
-
// @ts-ignore
|
|
490
|
-
accessibilityKeyShortcuts,
|
|
491
|
-
// @ts-ignore
|
|
492
|
-
accessibilityLabel,
|
|
493
|
-
// @ts-ignore
|
|
494
|
-
accessibilityLabelledBy,
|
|
495
|
-
// @ts-ignore
|
|
496
|
-
accessibilityLevel,
|
|
497
|
-
// @ts-ignore
|
|
498
|
-
accessibilityLiveRegion,
|
|
499
|
-
// @ts-ignore
|
|
500
|
-
accessibilityModal,
|
|
501
|
-
// @ts-ignore
|
|
502
|
-
accessibilityMultiline,
|
|
503
|
-
// @ts-ignore
|
|
504
|
-
accessibilityMultiSelectable,
|
|
505
|
-
// @ts-ignore
|
|
506
|
-
accessibilityOrientation,
|
|
507
|
-
// @ts-ignore
|
|
508
|
-
accessibilityOwns,
|
|
509
|
-
// @ts-ignore
|
|
510
|
-
accessibilityPlaceholder,
|
|
511
|
-
// @ts-ignore
|
|
512
|
-
accessibilityPosInSet,
|
|
513
|
-
// @ts-ignore
|
|
514
|
-
accessibilityPressed,
|
|
515
|
-
// @ts-ignore
|
|
516
|
-
accessibilityReadOnly,
|
|
517
|
-
// @ts-ignore
|
|
518
|
-
accessibilityRequired,
|
|
519
|
-
// @ts-ignore
|
|
520
|
-
accessibilityRole,
|
|
521
|
-
// @ts-ignore
|
|
522
|
-
accessibilityRoleDescription,
|
|
523
|
-
// @ts-ignore
|
|
524
|
-
accessibilityRowCount,
|
|
525
|
-
// @ts-ignore
|
|
526
|
-
accessibilityRowIndex,
|
|
527
|
-
// @ts-ignore
|
|
528
|
-
accessibilityRowSpan,
|
|
529
|
-
// @ts-ignore
|
|
530
|
-
accessibilitySelected,
|
|
531
|
-
// @ts-ignore
|
|
532
|
-
accessibilitySetSize,
|
|
533
|
-
// @ts-ignore
|
|
534
|
-
accessibilitySort,
|
|
535
|
-
// @ts-ignore
|
|
536
|
-
accessibilityValueMax,
|
|
537
|
-
// @ts-ignore
|
|
538
|
-
accessibilityValueMin,
|
|
539
|
-
// @ts-ignore
|
|
540
|
-
accessibilityValueNow,
|
|
541
|
-
// @ts-ignore
|
|
542
|
-
accessibilityValueText,
|
|
543
|
-
|
|
544
|
-
// deprecated
|
|
545
|
-
accessible,
|
|
546
|
-
accessibilityState,
|
|
547
|
-
accessibilityValue,
|
|
548
|
-
|
|
549
461
|
// android
|
|
550
462
|
collapsable,
|
|
551
463
|
focusable,
|
|
552
464
|
|
|
465
|
+
// deprecated,
|
|
466
|
+
accessible,
|
|
467
|
+
accessibilityDisabled,
|
|
468
|
+
|
|
553
469
|
onLayout,
|
|
554
470
|
|
|
555
471
|
...webProps
|
|
@@ -557,12 +473,11 @@ export function createComponent<
|
|
|
557
473
|
|
|
558
474
|
viewProps = webProps
|
|
559
475
|
|
|
560
|
-
assignNativePropsToWeb(elementType, viewProps, nonTamaguiProps)
|
|
561
|
-
|
|
562
476
|
if (!isRSC) {
|
|
563
|
-
|
|
477
|
+
usePlatformMethods(hostRef as RefObject<Element>)
|
|
478
|
+
|
|
479
|
+
useElementLayout(hostRef as RefObject<Element>, onLayout as any)
|
|
564
480
|
|
|
565
|
-
// from react-native-web
|
|
566
481
|
useResponderEvents(hostRef, {
|
|
567
482
|
onMoveShouldSetResponder,
|
|
568
483
|
onMoveShouldSetResponderCapture,
|
|
@@ -580,14 +495,7 @@ export function createComponent<
|
|
|
580
495
|
onSelectionChangeShouldSetResponderCapture,
|
|
581
496
|
onStartShouldSetResponder,
|
|
582
497
|
onStartShouldSetResponderCapture,
|
|
583
|
-
})
|
|
584
|
-
|
|
585
|
-
// from react-native-web
|
|
586
|
-
const platformMethodsRef = usePlatformMethods(viewProps)
|
|
587
|
-
|
|
588
|
-
const setRef = useMergeRefs(hostRef, platformMethodsRef, forwardedRef as any, setMounted)
|
|
589
|
-
|
|
590
|
-
viewProps.ref = setRef
|
|
498
|
+
} as any)
|
|
591
499
|
}
|
|
592
500
|
|
|
593
501
|
if (props.href != undefined && hrefAttrs != undefined) {
|
|
@@ -640,12 +548,10 @@ export function createComponent<
|
|
|
640
548
|
}
|
|
641
549
|
} else {
|
|
642
550
|
viewProps = nonTamaguiProps
|
|
643
|
-
if (forwardedRef) {
|
|
644
|
-
// @ts-ignore
|
|
645
|
-
viewProps.ref = forwardedRef
|
|
646
|
-
}
|
|
647
551
|
}
|
|
648
552
|
|
|
553
|
+
viewProps.ref = useComposedRefs(hostRef as any, forwardedRef, setMounted)
|
|
554
|
+
|
|
649
555
|
if (process.env.NODE_ENV === 'development' && !isText && isWeb && !staticConfig.isHOC) {
|
|
650
556
|
Children.toArray(props.children).forEach((item) => {
|
|
651
557
|
if (typeof item === 'string') {
|
|
@@ -672,8 +578,6 @@ export function createComponent<
|
|
|
672
578
|
|
|
673
579
|
let styles: any[]
|
|
674
580
|
|
|
675
|
-
const animationStyles = state.animation ? state.animation.style : null
|
|
676
|
-
|
|
677
581
|
if (isStringElement && shouldAvoidClasses && !shouldForcePseudo) {
|
|
678
582
|
styles = {
|
|
679
583
|
...defaultNativeStyle,
|
|
@@ -705,32 +609,16 @@ export function createComponent<
|
|
|
705
609
|
}
|
|
706
610
|
}
|
|
707
611
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
fontFamily = fontFamily.slice(1)
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
if (process.env.NODE_ENV === 'development') {
|
|
717
|
-
if (fontFamily?.startsWith(`var(`)) {
|
|
718
|
-
// eslint-disable-next-line no-console
|
|
719
|
-
console.warn(
|
|
720
|
-
`Received variable instead of resolved name of font, this is a bug. Please report on Github.`,
|
|
721
|
-
{
|
|
722
|
-
fontFamily,
|
|
723
|
-
props,
|
|
724
|
-
splitStyles,
|
|
725
|
-
staticConfig,
|
|
726
|
-
}
|
|
727
|
-
)
|
|
728
|
-
}
|
|
729
|
-
}
|
|
612
|
+
let fontFamily = isText ? splitStyles.fontFamily || staticConfig.defaultProps.fontFamily : null
|
|
613
|
+
if (fontFamily && fontFamily[0] === '$') {
|
|
614
|
+
fontFamily = fontFamily.slice(1)
|
|
615
|
+
}
|
|
616
|
+
const fontFamilyClassName = fontFamily ? `font_${fontFamily}` : ''
|
|
730
617
|
|
|
618
|
+
if (process.env.TAMAGUI_TARGET === 'web') {
|
|
731
619
|
const classList = [
|
|
732
620
|
componentName ? componentClassName : '',
|
|
733
|
-
|
|
621
|
+
fontFamilyClassName,
|
|
734
622
|
theme.className,
|
|
735
623
|
classNames ? Object.values(classNames).join(' ') : '',
|
|
736
624
|
]
|
|
@@ -738,10 +626,9 @@ export function createComponent<
|
|
|
738
626
|
const className = classList.join(' ')
|
|
739
627
|
const style = animationStyles ?? splitStyles.style
|
|
740
628
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
if (staticConfig.isReactNativeWeb || isAnimatedReactNativeWeb) {
|
|
629
|
+
if (isAnimatedReactNativeWeb) {
|
|
630
|
+
viewProps.style = style
|
|
631
|
+
} else if (isReactNativeWeb) {
|
|
745
632
|
const rnwStyle = { $$css: true }
|
|
746
633
|
for (const name of className.split(' ')) {
|
|
747
634
|
rnwStyle[name] = name
|
|
@@ -764,13 +651,9 @@ export function createComponent<
|
|
|
764
651
|
}
|
|
765
652
|
|
|
766
653
|
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
767
|
-
// add ref
|
|
768
|
-
const mergedRef = useMergeRefs(forwardedRef, hostRef, setMounted)
|
|
769
|
-
viewProps.ref = mergedRef
|
|
770
|
-
|
|
771
654
|
// swap out the right family based on weight/style
|
|
772
655
|
if (splitStyles.fontFamily) {
|
|
773
|
-
const faceInfo =
|
|
656
|
+
const faceInfo = tamaguiConfig.fontsParsed[splitStyles.fontFamily]?.face
|
|
774
657
|
if (faceInfo) {
|
|
775
658
|
const [weight, style] = (() => {
|
|
776
659
|
let weight: string | undefined
|
|
@@ -812,10 +695,7 @@ export function createComponent<
|
|
|
812
695
|
isHoverable &&
|
|
813
696
|
!!((pseudos && pseudos.hoverStyle) || onHoverIn || onHoverOut || onMouseEnter || onMouseLeave)
|
|
814
697
|
|
|
815
|
-
const handlesPressEvents = !
|
|
816
|
-
const pressKey = handlesPressEvents ? 'onPress' : 'onClick'
|
|
817
|
-
const pressInKey = handlesPressEvents ? 'onPressIn' : 'onMouseDown'
|
|
818
|
-
const pressOutKey = handlesPressEvents ? 'onPressOut' : 'onMouseUp'
|
|
698
|
+
const handlesPressEvents = !isWeb && !asChild
|
|
819
699
|
|
|
820
700
|
// check presence to prevent reparenting bugs, allows for onPress={x ? function : undefined} usage
|
|
821
701
|
const shouldAttach =
|
|
@@ -836,7 +716,7 @@ export function createComponent<
|
|
|
836
716
|
const events =
|
|
837
717
|
shouldAttach && !isRSC
|
|
838
718
|
? {
|
|
839
|
-
|
|
719
|
+
onPressOut: attachPress
|
|
840
720
|
? (e) => {
|
|
841
721
|
unPress()
|
|
842
722
|
onPressOut?.(e)
|
|
@@ -853,7 +733,7 @@ export function createComponent<
|
|
|
853
733
|
if (state.pressIn) {
|
|
854
734
|
next.press = true
|
|
855
735
|
}
|
|
856
|
-
if (
|
|
736
|
+
if (attachHover || state.pressIn) {
|
|
857
737
|
setStateShallow(next)
|
|
858
738
|
}
|
|
859
739
|
onHoverIn?.(e)
|
|
@@ -879,7 +759,7 @@ export function createComponent<
|
|
|
879
759
|
}
|
|
880
760
|
: undefined,
|
|
881
761
|
}),
|
|
882
|
-
|
|
762
|
+
onPressIn: attachPress
|
|
883
763
|
? (e) => {
|
|
884
764
|
setStateShallow({
|
|
885
765
|
press: true,
|
|
@@ -892,15 +772,15 @@ export function createComponent<
|
|
|
892
772
|
mouseUps.add(unPress)
|
|
893
773
|
}
|
|
894
774
|
}
|
|
895
|
-
:
|
|
896
|
-
|
|
775
|
+
: undefined,
|
|
776
|
+
onPress: attachPress
|
|
897
777
|
? (e) => {
|
|
898
778
|
unPress()
|
|
899
779
|
// @ts-ignore
|
|
900
780
|
onClick?.(e)
|
|
901
781
|
onPress?.(e)
|
|
902
782
|
}
|
|
903
|
-
:
|
|
783
|
+
: undefined,
|
|
904
784
|
|
|
905
785
|
// replicating TouchableWithoutFeedback
|
|
906
786
|
...(!isWeb && {
|
|
@@ -966,33 +846,6 @@ export function createComponent<
|
|
|
966
846
|
}
|
|
967
847
|
}
|
|
968
848
|
|
|
969
|
-
// EVENTS: web
|
|
970
|
-
if (!isRSC && isWeb) {
|
|
971
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
972
|
-
const [pressableProps] = usePressable(
|
|
973
|
-
events
|
|
974
|
-
? {
|
|
975
|
-
disabled,
|
|
976
|
-
...(hitSlop && {
|
|
977
|
-
hitSlop,
|
|
978
|
-
}),
|
|
979
|
-
onPressOut: events[pressOutKey],
|
|
980
|
-
onPressIn: events[pressInKey],
|
|
981
|
-
onPress: events[pressKey],
|
|
982
|
-
}
|
|
983
|
-
: {
|
|
984
|
-
disabled: true,
|
|
985
|
-
}
|
|
986
|
-
)
|
|
987
|
-
if (events) {
|
|
988
|
-
if (handlesPressEvents) {
|
|
989
|
-
Object.assign(viewProps, pressableProps)
|
|
990
|
-
} else {
|
|
991
|
-
Object.assign(viewProps, events)
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
|
|
996
849
|
// EVENTS native
|
|
997
850
|
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
998
851
|
// add focus events
|
|
@@ -1013,9 +866,6 @@ export function createComponent<
|
|
|
1013
866
|
// only ever create once, use .configure() to update later
|
|
1014
867
|
const pressability = usePressability(events)
|
|
1015
868
|
if (attachPress && events) {
|
|
1016
|
-
const dontComposePressabilityKeys = {
|
|
1017
|
-
onClick: true,
|
|
1018
|
-
}
|
|
1019
869
|
if (hitSlop) {
|
|
1020
870
|
viewProps.hitSlop = hitSlop
|
|
1021
871
|
}
|
|
@@ -1031,33 +881,32 @@ export function createComponent<
|
|
|
1031
881
|
content = createElement(elementType, viewProps, childEls)
|
|
1032
882
|
|
|
1033
883
|
if (process.env.TAMAGUI_TARGET === 'web') {
|
|
1034
|
-
|
|
1035
|
-
const isAnimatedRNWView = isAnimated && typeof elementType !== 'string' // assuming for now as reanimated is only driver
|
|
1036
|
-
const shouldWrapWithComponentTheme =
|
|
1037
|
-
!!theme.className &&
|
|
1038
|
-
isAnimatedRNWView &&
|
|
1039
|
-
getReturnVariablesAs(props, splitStyleState) === 'non-color-value'
|
|
1040
|
-
const shouldWrapWithHover = Boolean(events || isRSC) && attachHover
|
|
1041
|
-
|
|
1042
|
-
if (shouldWrapWithHover || shouldWrapWithComponentTheme) {
|
|
1043
|
-
const themeClassName = shouldWrapWithComponentTheme ? `${theme.className}` : ''
|
|
1044
|
-
const hoverClassName = shouldWrapWithHover ? 't_Hoverable' : ''
|
|
884
|
+
if (events) {
|
|
1045
885
|
content = (
|
|
1046
886
|
<span
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}
|
|
1051
|
-
{
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
})}
|
|
887
|
+
style={styleDisplayContents}
|
|
888
|
+
onMouseEnter={events.onMouseEnter}
|
|
889
|
+
onMouseLeave={events.onMouseLeave}
|
|
890
|
+
onClick={events.onPress}
|
|
891
|
+
onMouseDown={events.onPressIn}
|
|
892
|
+
onMouseUp={events.onPressOut}
|
|
893
|
+
onTouchStart={events.onPressIn}
|
|
894
|
+
onTouchEnd={events.onPressOut}
|
|
1056
895
|
>
|
|
1057
896
|
{content}
|
|
1058
897
|
</span>
|
|
1059
898
|
)
|
|
1060
899
|
}
|
|
900
|
+
|
|
901
|
+
// special weird case since there's a bug in RNW where we can't animate + pass style { $$css }
|
|
902
|
+
// but we need is_font classnames... need to see about RNW bug and then can remove this
|
|
903
|
+
if (isText && isAnimatedReactNativeWeb) {
|
|
904
|
+
content = (
|
|
905
|
+
<span className={fontFamilyClassName} style={styleDisplayContents}>
|
|
906
|
+
{content}
|
|
907
|
+
</span>
|
|
908
|
+
)
|
|
909
|
+
}
|
|
1061
910
|
}
|
|
1062
911
|
|
|
1063
912
|
if (process.env.NODE_ENV === 'development') {
|
|
@@ -1090,48 +939,44 @@ export function createComponent<
|
|
|
1090
939
|
component.displayName = staticConfig.componentName
|
|
1091
940
|
}
|
|
1092
941
|
|
|
1093
|
-
// Once configuration is run and all components are registered
|
|
1094
|
-
// get default props + className and analyze styles
|
|
1095
942
|
onConfiguredOnce((conf) => {
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
// do this to make sure shorthands don't duplicate with.. longhands
|
|
1116
|
-
mergeShorthands(staticConfig, tamaguiConfig)
|
|
943
|
+
// one time only setup
|
|
944
|
+
if (!tamaguiConfig) {
|
|
945
|
+
tamaguiConfig = conf
|
|
946
|
+
|
|
947
|
+
if (!defaultComponentState) {
|
|
948
|
+
defaultComponentState = {
|
|
949
|
+
hover: false,
|
|
950
|
+
press: false,
|
|
951
|
+
pressIn: false,
|
|
952
|
+
focus: false,
|
|
953
|
+
mounted: false,
|
|
954
|
+
mediaState: getInitialMediaState(),
|
|
955
|
+
}
|
|
956
|
+
defaultComponentStateMounted = {
|
|
957
|
+
...defaultComponentState,
|
|
958
|
+
mounted: true,
|
|
959
|
+
}
|
|
960
|
+
}
|
|
1117
961
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
}
|
|
962
|
+
if (tamaguiConfig.animations) {
|
|
963
|
+
AnimatedText = tamaguiConfig.animations.Text
|
|
964
|
+
AnimatedView = tamaguiConfig.animations.View
|
|
965
|
+
}
|
|
1123
966
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
967
|
+
if (!initialTheme) {
|
|
968
|
+
const next = conf.themes[conf.defaultTheme || Object.keys(conf.themes)[0]]
|
|
969
|
+
initialTheme = proxyThemeVariables(next)
|
|
970
|
+
if (!initialTheme && process.env.NODE_ENV === 'development') {
|
|
971
|
+
// eslint-disable-next-line no-console
|
|
972
|
+
console.log(`Warning: Missing theme`)
|
|
973
|
+
}
|
|
1130
974
|
}
|
|
1131
975
|
}
|
|
1132
976
|
|
|
1133
|
-
//
|
|
1134
|
-
|
|
977
|
+
// per-component setup
|
|
978
|
+
// do this to make sure shorthands don't duplicate with.. longhands
|
|
979
|
+
mergeShorthands(staticConfig, tamaguiConfig)
|
|
1135
980
|
|
|
1136
981
|
let defaultPropsIn = staticConfig.defaultProps || {}
|
|
1137
982
|
|
|
@@ -1140,23 +985,18 @@ export function createComponent<
|
|
|
1140
985
|
// find last unprocessed and process
|
|
1141
986
|
const parentNames = [...(staticConfig.parentNames || []), staticConfig.componentName]
|
|
1142
987
|
|
|
1143
|
-
if (
|
|
988
|
+
if (tamaguiConfig.defaultProps && parentNames && staticConfig.componentName) {
|
|
1144
989
|
defaultPropsIn = mergeConfigDefaultProps(
|
|
1145
990
|
staticConfig.componentName,
|
|
1146
991
|
defaultPropsIn,
|
|
1147
|
-
|
|
992
|
+
tamaguiConfig.defaultProps,
|
|
1148
993
|
parentNames,
|
|
1149
|
-
|
|
994
|
+
tamaguiConfig
|
|
1150
995
|
)
|
|
1151
996
|
}
|
|
1152
997
|
|
|
1153
998
|
const debug = defaultPropsIn['debug']
|
|
1154
999
|
|
|
1155
|
-
if (process.env.NODE_ENV === 'development' && debug === 'break') {
|
|
1156
|
-
// eslint-disable-next-line no-debugger
|
|
1157
|
-
debugger
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
1000
|
// remove all classNames
|
|
1161
1001
|
const [parentProps, parentClassNames] = mergeProps(defaultPropsIn, {}, true)
|
|
1162
1002
|
|
|
@@ -1278,12 +1118,14 @@ export const Spacer = createComponent<SpacerProps>({
|
|
|
1278
1118
|
memo: true,
|
|
1279
1119
|
componentName: 'Spacer',
|
|
1280
1120
|
validStyles,
|
|
1121
|
+
|
|
1281
1122
|
defaultProps: {
|
|
1282
1123
|
...stackDefaultStyles,
|
|
1283
1124
|
// avoid nesting issues
|
|
1284
1125
|
tag: 'span',
|
|
1285
1126
|
size: true,
|
|
1286
1127
|
},
|
|
1128
|
+
|
|
1287
1129
|
variants: {
|
|
1288
1130
|
size: {
|
|
1289
1131
|
'...size': (size, { tokens }) => {
|
|
@@ -1316,10 +1158,6 @@ export const Spacer = createComponent<SpacerProps>({
|
|
|
1316
1158
|
both: {},
|
|
1317
1159
|
},
|
|
1318
1160
|
} as const,
|
|
1319
|
-
|
|
1320
|
-
defaultVariants: {
|
|
1321
|
-
direction: 'both',
|
|
1322
|
-
},
|
|
1323
1161
|
})
|
|
1324
1162
|
|
|
1325
1163
|
export type SpacedChildrenProps = {
|
|
@@ -1379,7 +1217,7 @@ export function spacedChildren({
|
|
|
1379
1217
|
if (hasSpace) {
|
|
1380
1218
|
final.push(
|
|
1381
1219
|
createSpacer({
|
|
1382
|
-
key: `_${index}
|
|
1220
|
+
key: `_${index}_00tmgui`,
|
|
1383
1221
|
direction,
|
|
1384
1222
|
space,
|
|
1385
1223
|
spaceFlex,
|
|
@@ -1394,7 +1232,7 @@ export function spacedChildren({
|
|
|
1394
1232
|
if (hasSpace) {
|
|
1395
1233
|
final.push(
|
|
1396
1234
|
createSpacer({
|
|
1397
|
-
key: `_${index}
|
|
1235
|
+
key: `_${index}01tmgui`,
|
|
1398
1236
|
direction,
|
|
1399
1237
|
space,
|
|
1400
1238
|
spaceFlex,
|
|
@@ -1404,7 +1242,7 @@ export function spacedChildren({
|
|
|
1404
1242
|
} else {
|
|
1405
1243
|
final.push(
|
|
1406
1244
|
createSpacer({
|
|
1407
|
-
key: `_${index}
|
|
1245
|
+
key: `_${index}02tmgui`,
|
|
1408
1246
|
direction,
|
|
1409
1247
|
space,
|
|
1410
1248
|
spaceFlex,
|
|
@@ -1438,48 +1276,6 @@ function isUnspaced(child: React.ReactNode) {
|
|
|
1438
1276
|
return child?.['type']?.['isVisuallyHidden'] || child?.['type']?.['isUnspaced']
|
|
1439
1277
|
}
|
|
1440
1278
|
|
|
1441
|
-
function AbsoluteFill(props: { children?: any }) {
|
|
1442
|
-
return (
|
|
1443
|
-
<View pointerEvents="box-none" style={absoluteFill}>
|
|
1444
|
-
{props.children}
|
|
1445
|
-
</View>
|
|
1446
|
-
)
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
const absoluteFill = {
|
|
1450
|
-
position: 'absolute',
|
|
1451
|
-
top: 0,
|
|
1452
|
-
left: 0,
|
|
1453
|
-
right: 0,
|
|
1454
|
-
bottom: 0,
|
|
1455
|
-
} as const
|
|
1456
|
-
|
|
1457
|
-
// this can be done with CSS entirely right?
|
|
1458
|
-
// const shouldWrapTextAncestor = isWeb && isText && !hasTextAncestor
|
|
1459
|
-
// if (shouldWrapTextAncestor) {
|
|
1460
|
-
// // from react-native-web
|
|
1461
|
-
// content = createElement(TextAncestorContext.Provider, { value: true }, content)
|
|
1462
|
-
// }
|
|
1463
|
-
|
|
1464
|
-
export function processIDRefList(idRefList: string | Array<string>): string {
|
|
1465
|
-
return Array.isArray(idRefList) ? idRefList.join(' ') : idRefList
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
export const accessibilityRoleToWebRole = {
|
|
1469
|
-
adjustable: 'slider',
|
|
1470
|
-
button: 'button',
|
|
1471
|
-
header: 'heading',
|
|
1472
|
-
image: 'img',
|
|
1473
|
-
imagebutton: null,
|
|
1474
|
-
keyboardkey: null,
|
|
1475
|
-
label: null,
|
|
1476
|
-
link: 'link',
|
|
1477
|
-
none: 'presentation',
|
|
1478
|
-
search: 'search',
|
|
1479
|
-
summary: 'region',
|
|
1480
|
-
text: null,
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
1279
|
function addPseudoToStyles(
|
|
1484
1280
|
styles: any[],
|
|
1485
1281
|
initialPseudos: SplitStyleResult['pseudos'],
|
|
@@ -1600,3 +1396,45 @@ function merge(base: ViewStyle, next: ViewStyle) {
|
|
|
1600
1396
|
}
|
|
1601
1397
|
}
|
|
1602
1398
|
}
|
|
1399
|
+
|
|
1400
|
+
// react native compat (web only)
|
|
1401
|
+
function usePlatformMethods(hostRef: RefObject<Element>) {
|
|
1402
|
+
useIsomorphicLayoutEffect(() => {
|
|
1403
|
+
const node = hostRef.current
|
|
1404
|
+
if (!node) return
|
|
1405
|
+
// @ts-ignore
|
|
1406
|
+
node.measure = (callback) => measureLayout(node, null, callback)
|
|
1407
|
+
// @ts-ignore
|
|
1408
|
+
node.measureLayout = (relativeToNode, success) => measureLayout(node, relativeToNode, success)
|
|
1409
|
+
// @ts-ignore
|
|
1410
|
+
node.measureInWindow = (callback) => {
|
|
1411
|
+
if (!node) return
|
|
1412
|
+
setTimeout(() => {
|
|
1413
|
+
const { height, left, top, width } = getRect(node as HTMLElement)!
|
|
1414
|
+
callback(left, top, width, height)
|
|
1415
|
+
}, 0)
|
|
1416
|
+
}
|
|
1417
|
+
}, [hostRef])
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
const AbsoluteFill: any = createComponent({
|
|
1421
|
+
componentName: 'AbsoluteFill',
|
|
1422
|
+
defaultProps: {
|
|
1423
|
+
...stackDefaultStyles,
|
|
1424
|
+
flexDirection: 'column',
|
|
1425
|
+
position: 'absolute',
|
|
1426
|
+
top: 0,
|
|
1427
|
+
right: 0,
|
|
1428
|
+
bottom: 0,
|
|
1429
|
+
left: 0,
|
|
1430
|
+
pointerEvents: 'box-none',
|
|
1431
|
+
},
|
|
1432
|
+
})
|
|
1433
|
+
|
|
1434
|
+
const styleDisplayContents = {
|
|
1435
|
+
display: 'contents',
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
const dontComposePressabilityKeys = {
|
|
1439
|
+
onClick: true,
|
|
1440
|
+
}
|