@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.
Files changed (232) hide show
  1. package/dist/cjs/Tamagui.js +4 -2
  2. package/dist/cjs/Tamagui.js.map +2 -2
  3. package/dist/cjs/config.js +1 -2
  4. package/dist/cjs/config.js.map +2 -2
  5. package/dist/cjs/constants/constants.js +13 -8
  6. package/dist/cjs/constants/constants.js.map +2 -2
  7. package/dist/cjs/contexts/TextAncestorContext.js +3 -16
  8. package/dist/cjs/contexts/TextAncestorContext.js.map +3 -3
  9. package/dist/cjs/createComponent.js +196 -284
  10. package/dist/cjs/createComponent.js.map +2 -2
  11. package/dist/cjs/createTamagui.js +15 -16
  12. package/dist/cjs/createTamagui.js.map +3 -3
  13. package/dist/cjs/createVariable.js +1 -2
  14. package/dist/cjs/createVariable.js.map +2 -2
  15. package/dist/cjs/helpers/ThemeManager.js +7 -14
  16. package/dist/cjs/helpers/ThemeManager.js.map +2 -2
  17. package/dist/cjs/helpers/{createShallowUpdate.js → cache.js} +20 -21
  18. package/dist/cjs/helpers/cache.js.map +7 -0
  19. package/dist/cjs/helpers/createMediaStyle.js +14 -8
  20. package/dist/cjs/helpers/createMediaStyle.js.map +2 -2
  21. package/dist/cjs/helpers/extendStaticConfig.js +0 -1
  22. package/dist/cjs/helpers/extendStaticConfig.js.map +2 -2
  23. package/dist/cjs/helpers/getSplitStyles.js +214 -94
  24. package/dist/cjs/helpers/getSplitStyles.js.map +3 -3
  25. package/dist/cjs/helpers/getStylesAtomic.js +16 -36
  26. package/dist/cjs/helpers/getStylesAtomic.js.map +3 -3
  27. package/dist/cjs/helpers/getVariantExtras.js +2 -1
  28. package/dist/cjs/helpers/getVariantExtras.js.map +2 -2
  29. package/dist/cjs/helpers/insertStyleRule.js +14 -6
  30. package/dist/cjs/helpers/insertStyleRule.js.map +2 -2
  31. package/dist/cjs/helpers/matchMedia.js.map +2 -2
  32. package/dist/cjs/helpers/mergeTransform.js.map +1 -1
  33. package/dist/cjs/helpers/normalizeValueWithProperty.js +32 -2
  34. package/dist/cjs/helpers/normalizeValueWithProperty.js.map +2 -2
  35. package/dist/cjs/helpers/proxyThemeVariables.js +2 -7
  36. package/dist/cjs/helpers/proxyThemeVariables.js.map +2 -2
  37. package/dist/cjs/helpers/useShallowSetState.js.map +2 -2
  38. package/dist/cjs/hooks/getThemeUnwrapped.js +1 -3
  39. package/dist/cjs/hooks/getThemeUnwrapped.js.map +2 -2
  40. package/dist/cjs/hooks/useElementLayout.js +92 -0
  41. package/dist/cjs/hooks/useElementLayout.js.map +7 -0
  42. package/dist/cjs/hooks/useIsTouchDevice.js +2 -10
  43. package/dist/cjs/hooks/useIsTouchDevice.js.map +2 -2
  44. package/dist/cjs/hooks/useMedia.js +79 -85
  45. package/dist/cjs/hooks/useMedia.js.map +2 -2
  46. package/dist/cjs/hooks/useMedia.test.js +2 -0
  47. package/dist/cjs/{helpers/validate.js.map → hooks/useMedia.test.js.map} +0 -0
  48. package/dist/cjs/hooks/usePressablePressResponder.js +370 -0
  49. package/dist/cjs/hooks/usePressablePressResponder.js.map +7 -0
  50. package/dist/cjs/hooks/useSafeRef.js +13 -15
  51. package/dist/cjs/hooks/useSafeRef.js.map +2 -2
  52. package/dist/cjs/hooks/useTheme.js +5 -5
  53. package/dist/cjs/hooks/useTheme.js.map +2 -2
  54. package/dist/cjs/index.js +1 -17
  55. package/dist/cjs/index.js.map +2 -2
  56. package/dist/cjs/static.js +0 -20
  57. package/dist/cjs/static.js.map +2 -2
  58. package/dist/cjs/styled.js +4 -22
  59. package/dist/cjs/styled.js.map +2 -2
  60. package/dist/cjs/types.js.map +1 -1
  61. package/dist/cjs/{hooks/useIsSSR.js → views/AbsoluteFill.js} +18 -23
  62. package/dist/cjs/views/AbsoluteFill.js.map +7 -0
  63. package/dist/cjs/views/AbsoluteFill.native.js +45 -0
  64. package/dist/cjs/views/AbsoluteFill.native.js.map +7 -0
  65. package/dist/cjs/views/FontLanguage.native.js.map +2 -2
  66. package/dist/cjs/views/Stack.js.map +1 -1
  67. package/dist/cjs/views/TamaguiProvider.js +3 -2
  68. package/dist/cjs/views/TamaguiProvider.js.map +2 -2
  69. package/dist/cjs/views/Text.js.map +1 -1
  70. package/dist/cjs/views/ThemeReset.js +10 -10
  71. package/dist/cjs/views/ThemeReset.js.map +2 -2
  72. package/dist/esm/Tamagui.js +4 -2
  73. package/dist/esm/Tamagui.js.map +2 -2
  74. package/dist/esm/config.js +1 -2
  75. package/dist/esm/config.js.map +2 -2
  76. package/dist/esm/constants/constants.js +11 -7
  77. package/dist/esm/constants/constants.js.map +2 -2
  78. package/dist/esm/contexts/TextAncestorContext.js +2 -13
  79. package/dist/esm/contexts/TextAncestorContext.js.map +2 -2
  80. package/dist/esm/createComponent.js +195 -286
  81. package/dist/esm/createComponent.js.map +2 -2
  82. package/dist/esm/createTamagui.js +15 -16
  83. package/dist/esm/createTamagui.js.map +3 -3
  84. package/dist/esm/createVariable.js +1 -2
  85. package/dist/esm/createVariable.js.map +2 -2
  86. package/dist/esm/helpers/ThemeManager.js +7 -14
  87. package/dist/esm/helpers/ThemeManager.js.map +2 -2
  88. package/dist/esm/helpers/cache.js +18 -0
  89. package/dist/esm/helpers/cache.js.map +7 -0
  90. package/dist/esm/helpers/createMediaStyle.js +14 -8
  91. package/dist/esm/helpers/createMediaStyle.js.map +2 -2
  92. package/dist/esm/helpers/extendStaticConfig.js +0 -1
  93. package/dist/esm/helpers/extendStaticConfig.js.map +2 -2
  94. package/dist/esm/helpers/getSplitStyles.js +223 -95
  95. package/dist/esm/helpers/getSplitStyles.js.map +3 -3
  96. package/dist/esm/helpers/getStylesAtomic.js +13 -26
  97. package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
  98. package/dist/esm/helpers/getVariantExtras.js +2 -1
  99. package/dist/esm/helpers/getVariantExtras.js.map +2 -2
  100. package/dist/esm/helpers/insertStyleRule.js +14 -6
  101. package/dist/esm/helpers/insertStyleRule.js.map +2 -2
  102. package/dist/esm/helpers/matchMedia.js.map +2 -2
  103. package/dist/esm/helpers/mergeTransform.js.map +1 -1
  104. package/dist/esm/helpers/normalizeValueWithProperty.js +30 -1
  105. package/dist/esm/helpers/normalizeValueWithProperty.js.map +2 -2
  106. package/dist/esm/helpers/proxyThemeVariables.js +2 -7
  107. package/dist/esm/helpers/proxyThemeVariables.js.map +2 -2
  108. package/dist/esm/helpers/useShallowSetState.js.map +2 -2
  109. package/dist/esm/hooks/getThemeUnwrapped.js +1 -3
  110. package/dist/esm/hooks/getThemeUnwrapped.js.map +2 -2
  111. package/dist/esm/hooks/useElementLayout.js +66 -0
  112. package/dist/esm/hooks/useElementLayout.js.map +7 -0
  113. package/dist/esm/hooks/useIsTouchDevice.js +3 -11
  114. package/dist/esm/hooks/useIsTouchDevice.js.map +2 -2
  115. package/dist/esm/hooks/useMedia.js +76 -84
  116. package/dist/esm/hooks/useMedia.js.map +2 -2
  117. package/dist/esm/hooks/useMedia.test.js +1 -0
  118. package/dist/esm/{helpers/validate.js.map → hooks/useMedia.test.js.map} +0 -0
  119. package/dist/esm/hooks/usePressablePressResponder.js +346 -0
  120. package/dist/esm/hooks/usePressablePressResponder.js.map +7 -0
  121. package/dist/esm/hooks/useSafeRef.js +13 -15
  122. package/dist/esm/hooks/useSafeRef.js.map +2 -2
  123. package/dist/esm/hooks/useTheme.js +5 -5
  124. package/dist/esm/hooks/useTheme.js.map +2 -2
  125. package/dist/esm/index.js +1 -14
  126. package/dist/esm/index.js.map +2 -2
  127. package/dist/esm/static.js +0 -14
  128. package/dist/esm/static.js.map +2 -2
  129. package/dist/esm/styled.js +4 -22
  130. package/dist/esm/styled.js.map +2 -2
  131. package/dist/esm/views/AbsoluteFill.js +17 -0
  132. package/dist/esm/views/AbsoluteFill.js.map +7 -0
  133. package/dist/esm/views/AbsoluteFill.native.js +21 -0
  134. package/dist/esm/views/AbsoluteFill.native.js.map +7 -0
  135. package/dist/esm/views/FontLanguage.native.js.map +2 -2
  136. package/dist/esm/views/Stack.js.map +1 -1
  137. package/dist/esm/views/TamaguiProvider.js +5 -4
  138. package/dist/esm/views/TamaguiProvider.js.map +2 -2
  139. package/dist/esm/views/Text.js.map +1 -1
  140. package/dist/esm/views/ThemeReset.js +10 -10
  141. package/dist/esm/views/ThemeReset.js.map +2 -2
  142. package/package.json +14 -14
  143. package/src/Tamagui.ts +7 -3
  144. package/src/config.ts +2 -3
  145. package/src/constants/constants.ts +10 -6
  146. package/src/contexts/TextAncestorContext.tsx +1 -8
  147. package/src/createComponent.tsx +250 -412
  148. package/src/createTamagui.ts +16 -19
  149. package/src/createVariable.ts +1 -3
  150. package/src/helpers/ThemeManager.tsx +7 -15
  151. package/src/helpers/cache.ts +18 -0
  152. package/src/helpers/createMediaStyle.ts +16 -9
  153. package/src/helpers/createProxy.ts +16 -0
  154. package/src/helpers/extendStaticConfig.ts +0 -1
  155. package/src/helpers/getSplitStyles.tsx +259 -152
  156. package/src/helpers/getStylesAtomic.ts +14 -34
  157. package/src/helpers/getVariantExtras.tsx +2 -1
  158. package/src/helpers/insertStyleRule.tsx +16 -8
  159. package/src/helpers/matchMedia.ts +1 -0
  160. package/src/helpers/mergeTransform.ts +1 -1
  161. package/src/helpers/normalizeValueWithProperty.ts +30 -0
  162. package/src/helpers/proxyThemeVariables.tsx +3 -8
  163. package/src/helpers/useShallowSetState.tsx +0 -1
  164. package/src/hooks/getThemeUnwrapped.tsx +1 -2
  165. package/src/hooks/useElementLayout.tsx +90 -0
  166. package/src/hooks/useIsTouchDevice.tsx +3 -17
  167. package/src/hooks/useMedia.tsx +82 -88
  168. package/src/hooks/useSafeRef.ts +17 -18
  169. package/src/hooks/useTheme.tsx +6 -5
  170. package/src/index.ts +1 -11
  171. package/src/static.ts +0 -10
  172. package/src/styled.tsx +15 -33
  173. package/src/types.tsx +58 -55
  174. package/src/views/FontLanguage.native.tsx +1 -0
  175. package/src/views/Stack.tsx +1 -1
  176. package/src/views/TamaguiProvider.tsx +5 -5
  177. package/src/views/Text.tsx +1 -1
  178. package/src/views/ThemeReset.tsx +11 -11
  179. package/types/Tamagui.d.ts +6 -4
  180. package/types/constants/constants.d.ts +14 -3
  181. package/types/contexts/TextAncestorContext.d.ts +1 -3
  182. package/types/createComponent.d.ts +0 -15
  183. package/types/helpers/ThemeManager.d.ts +2 -3
  184. package/types/helpers/cache.d.ts +12 -0
  185. package/types/helpers/calc.d.ts +0 -16
  186. package/types/helpers/createMediaStyle.d.ts +1 -1
  187. package/types/helpers/createProxy.d.ts +2 -0
  188. package/types/helpers/getSplitStyles.d.ts +6 -10
  189. package/types/helpers/getStylesAtomic.d.ts +1 -5
  190. package/types/helpers/insertStyleRule.d.ts +2 -2
  191. package/types/helpers/mergeTransform.d.ts +1 -1
  192. package/types/helpers/normalizeValueWithProperty.d.ts +1 -0
  193. package/types/hooks/useElementLayout.d.ts +27 -0
  194. package/types/hooks/useMedia.d.ts +3 -1
  195. package/types/hooks/useMedia.test.d.ts +1 -0
  196. package/types/hooks/usePressablePressResponder.d.ts +84 -0
  197. package/types/index.d.ts +1 -11
  198. package/types/static.d.ts +0 -1
  199. package/types/types.d.ts +42 -44
  200. package/types/views/AbsoluteFill.d.ts +5 -0
  201. package/types/views/AbsoluteFill.native.d.ts +3 -0
  202. package/types/views/Stack.d.ts +1 -1
  203. package/types/views/Text.d.ts +1 -1
  204. package/dist/cjs/constants/platform.js +0 -74
  205. package/dist/cjs/constants/platform.js.map +0 -7
  206. package/dist/cjs/constants/platform.native.js +0 -62
  207. package/dist/cjs/constants/platform.native.js.map +0 -7
  208. package/dist/cjs/helpers/createShallowUpdate.js.map +0 -7
  209. package/dist/cjs/helpers/validate.js +0 -2
  210. package/dist/cjs/hooks/useDidFinishSSR.js +0 -60
  211. package/dist/cjs/hooks/useDidFinishSSR.js.map +0 -7
  212. package/dist/cjs/hooks/useIsSSR.js.map +0 -7
  213. package/dist/esm/constants/platform.js +0 -39
  214. package/dist/esm/constants/platform.js.map +0 -7
  215. package/dist/esm/constants/platform.native.js +0 -28
  216. package/dist/esm/constants/platform.native.js.map +0 -7
  217. package/dist/esm/helpers/createShallowUpdate.js +0 -20
  218. package/dist/esm/helpers/createShallowUpdate.js.map +0 -7
  219. package/dist/esm/helpers/validate.js +0 -1
  220. package/dist/esm/hooks/useDidFinishSSR.js +0 -35
  221. package/dist/esm/hooks/useDidFinishSSR.js.map +0 -7
  222. package/dist/esm/hooks/useIsSSR.js +0 -22
  223. package/dist/esm/hooks/useIsSSR.js.map +0 -7
  224. package/src/helpers/assignNativePropsToWeb.tsx +0 -178
  225. package/src/helpers/calc.ts +0 -68
  226. package/src/helpers/getFont.tsx +0 -43
  227. package/src/helpers/getStackSize.ts +0 -22
  228. package/src/helpers/startTransition.ts +0 -4
  229. package/src/hooks/useConstant.tsx +0 -19
  230. package/src/hooks/useIsMounted.ts +0 -16
  231. package/src/hooks/usePressable.tsx +0 -9
  232. package/src/hooks/useUnmountEffect.ts +0 -5
@@ -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
- useElementLayout,
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 { getConfig, onConfiguredOnce } from './config'
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
- let initialTheme: any
92
- let config: TamaguiInternalConfig
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
- let tamaguiConfig: TamaguiInternalConfig
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
- const states = useServerState<TamaguiComponentState>(defaultComponentState!)
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?.classNames,
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
- const setState = states[1]
178
- const setStateShallow = useShallowSetState(setState)
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 = staticConfig.isReactNativeWeb ? 'rnw' : 'tamagui'
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
- // lets make changing the key mandatory for adding/removing animations
267
- // reason is animations are heavy no way around it, and must be run inline here (🙅 loading as a sub-component)
268
- // because they need to sync update on first render. it's pretty rare too going to/from no animation => animation
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 animationState = useAnimations(propsWithAnimation, {
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
- // must be properly memoized
347
- if (animationState !== state.animation) {
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' && !staticConfig.isReactNativeWeb) {
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
- useElementLayout(hostRef, onLayout)
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
- if (process.env.TAMAGUI_TARGET === 'web') {
709
- let fontFamily = isText
710
- ? splitStyles.fontFamily || staticConfig.defaultProps.fontFamily
711
- : null
712
- if (fontFamily && fontFamily[0] === '$') {
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
- fontFamily ? `font_${fontFamily}` : '',
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
- // TODO this is specific to reanimated rn
742
- const isAnimatedReactNativeWeb = props.animation && avoidClassesWhileAnimating
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 = config.fontsParsed[splitStyles.fontFamily]?.face
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 = !isStringElement && !asChild
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
- [pressOutKey]: attachPress
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 (Object.keys(next).length) {
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
- [pressInKey]: attachPress
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
- : null,
896
- [pressKey]: attachPress
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
- : null,
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
- // only necessary when animating because some AnimatedView which wraps RNW View doesn't forward dataSet className
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
- className={`${hoverClassName} ${themeClassName}`}
1048
- style={{
1049
- display: 'contents',
1050
- }}
1051
- {...(events &&
1052
- shouldWrapWithHover && {
1053
- onMouseEnter: events.onMouseEnter,
1054
- onMouseLeave: events.onMouseLeave,
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
- if (!defaultComponentState) {
1097
- defaultComponentState = Object.freeze({
1098
- hover: false,
1099
- press: false,
1100
- pressIn: false,
1101
- focus: false,
1102
- // only used by enterStyle
1103
- mounted: false,
1104
- animation: null,
1105
- mediaState: getInitialMediaState(),
1106
- })
1107
- }
1108
-
1109
- // in static mode we just use these to lookup configuration
1110
- // ... we likely want this? need to test
1111
- if (process.env.IS_STATIC === 'is_static') return
1112
-
1113
- tamaguiConfig = conf
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
- if (tamaguiConfig.animations) {
1119
- avoidClassesWhileAnimating = !!tamaguiConfig.animations.avoidClasses
1120
- AnimatedText = tamaguiConfig.animations.Text
1121
- AnimatedView = tamaguiConfig.animations.View
1122
- }
962
+ if (tamaguiConfig.animations) {
963
+ AnimatedText = tamaguiConfig.animations.Text
964
+ AnimatedView = tamaguiConfig.animations.View
965
+ }
1123
966
 
1124
- if (!initialTheme) {
1125
- const next = conf.themes[conf.defaultTheme || Object.keys(conf.themes)[0]]
1126
- initialTheme = proxyThemeVariables(next)
1127
- if (!initialTheme && process.env.NODE_ENV === 'development') {
1128
- // eslint-disable-next-line no-console
1129
- console.log(`Warning: Missing theme`)
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
- // adds in user defined default props
1134
- config = getConfig()
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 (config.defaultProps && parentNames && staticConfig.componentName) {
988
+ if (tamaguiConfig.defaultProps && parentNames && staticConfig.componentName) {
1144
989
  defaultPropsIn = mergeConfigDefaultProps(
1145
990
  staticConfig.componentName,
1146
991
  defaultPropsIn,
1147
- config.defaultProps,
992
+ tamaguiConfig.defaultProps,
1148
993
  parentNames,
1149
- conf
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}_before_sep_spacer`,
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}_after_sep_spacer`,
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}_spacer`,
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
+ }