@tamagui/web 1.46.2 → 1.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/dist/cjs/constants/constants.js +15 -15
  2. package/dist/cjs/constants/constants.js.map +1 -1
  3. package/dist/cjs/createComponent.js +82 -106
  4. package/dist/cjs/createComponent.js.map +1 -1
  5. package/dist/cjs/createTamagui.js +0 -1
  6. package/dist/cjs/createTamagui.js.map +1 -1
  7. package/dist/cjs/helpers/ThemeManager.js +6 -5
  8. package/dist/cjs/helpers/ThemeManager.js.map +1 -1
  9. package/dist/cjs/helpers/getSplitStyles.js +78 -98
  10. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  11. package/dist/cjs/helpers/getStylesAtomic.js +7 -7
  12. package/dist/cjs/helpers/getStylesAtomic.js.map +1 -1
  13. package/dist/cjs/helpers/getVariantExtras.js +2 -10
  14. package/dist/cjs/helpers/getVariantExtras.js.map +1 -1
  15. package/dist/cjs/helpers/isTamaguiComponent.js +1 -1
  16. package/dist/cjs/helpers/isTamaguiComponent.js.map +1 -1
  17. package/dist/cjs/helpers/mergeProps.js +6 -14
  18. package/dist/cjs/helpers/mergeProps.js.map +1 -1
  19. package/dist/cjs/helpers/normalizeColor.js +2 -1
  20. package/dist/cjs/helpers/normalizeColor.js.map +1 -1
  21. package/dist/cjs/helpers/normalizeValueWithProperty.js +5 -56
  22. package/dist/cjs/helpers/normalizeValueWithProperty.js.map +1 -1
  23. package/dist/cjs/helpers/{createPropMapper.js → propMapper.js} +64 -139
  24. package/dist/cjs/helpers/propMapper.js.map +6 -0
  25. package/dist/cjs/helpers/pseudoDescriptors.js +0 -1
  26. package/dist/cjs/helpers/pseudoDescriptors.js.map +1 -1
  27. package/dist/cjs/helpers/useShallowSetState.js +9 -17
  28. package/dist/cjs/helpers/useShallowSetState.js.map +1 -1
  29. package/dist/cjs/helpers/withStaticProperties.js +9 -0
  30. package/dist/cjs/helpers/withStaticProperties.js.map +1 -1
  31. package/dist/cjs/hooks/useMedia.js +7 -9
  32. package/dist/cjs/hooks/useMedia.js.map +1 -1
  33. package/dist/cjs/hooks/useStyle.js +5 -2
  34. package/dist/cjs/hooks/useStyle.js.map +1 -1
  35. package/dist/cjs/hooks/useTheme.js +28 -32
  36. package/dist/cjs/hooks/useTheme.js.map +1 -1
  37. package/dist/cjs/index.js +2 -2
  38. package/dist/cjs/index.js.map +1 -1
  39. package/dist/cjs/views/Stack.js +1 -4
  40. package/dist/cjs/views/Stack.js.map +1 -1
  41. package/dist/cjs/views/Theme.js +2 -2
  42. package/dist/cjs/views/Theme.js.map +1 -1
  43. package/dist/cjs/views/ThemeDebug.js +2 -2
  44. package/dist/cjs/views/ThemeDebug.js.map +1 -1
  45. package/dist/esm/constants/constants.js +14 -13
  46. package/dist/esm/constants/constants.js.map +1 -1
  47. package/dist/esm/createComponent.js +82 -106
  48. package/dist/esm/createComponent.js.map +1 -1
  49. package/dist/esm/createTamagui.js +0 -1
  50. package/dist/esm/createTamagui.js.map +1 -1
  51. package/dist/esm/helpers/ThemeManager.js +6 -5
  52. package/dist/esm/helpers/ThemeManager.js.map +1 -1
  53. package/dist/esm/helpers/getSplitStyles.js +77 -97
  54. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  55. package/dist/esm/helpers/getStylesAtomic.js +7 -7
  56. package/dist/esm/helpers/getStylesAtomic.js.map +1 -1
  57. package/dist/esm/helpers/getVariantExtras.js +2 -10
  58. package/dist/esm/helpers/getVariantExtras.js.map +1 -1
  59. package/dist/esm/helpers/isTamaguiComponent.js +1 -1
  60. package/dist/esm/helpers/isTamaguiComponent.js.map +1 -1
  61. package/dist/esm/helpers/mergeProps.js +6 -14
  62. package/dist/esm/helpers/mergeProps.js.map +1 -1
  63. package/dist/esm/helpers/normalizeColor.js +2 -1
  64. package/dist/esm/helpers/normalizeColor.js.map +1 -1
  65. package/dist/esm/helpers/normalizeValueWithProperty.js +5 -56
  66. package/dist/esm/helpers/normalizeValueWithProperty.js.map +1 -1
  67. package/dist/esm/helpers/{createPropMapper.js → propMapper.js} +57 -132
  68. package/dist/esm/helpers/propMapper.js.map +6 -0
  69. package/dist/esm/helpers/pseudoDescriptors.js +0 -1
  70. package/dist/esm/helpers/pseudoDescriptors.js.map +1 -1
  71. package/dist/esm/helpers/useShallowSetState.js +9 -17
  72. package/dist/esm/helpers/useShallowSetState.js.map +1 -1
  73. package/dist/esm/helpers/withStaticProperties.js +9 -0
  74. package/dist/esm/helpers/withStaticProperties.js.map +1 -1
  75. package/dist/esm/hooks/useMedia.js +8 -10
  76. package/dist/esm/hooks/useMedia.js.map +1 -1
  77. package/dist/esm/hooks/useStyle.js +5 -2
  78. package/dist/esm/hooks/useStyle.js.map +1 -1
  79. package/dist/esm/hooks/useTheme.js +28 -32
  80. package/dist/esm/hooks/useTheme.js.map +1 -1
  81. package/dist/esm/index.js +1 -1
  82. package/dist/esm/index.js.map +1 -1
  83. package/dist/esm/views/Stack.js +1 -4
  84. package/dist/esm/views/Stack.js.map +1 -1
  85. package/dist/esm/views/Theme.js +2 -2
  86. package/dist/esm/views/Theme.js.map +1 -1
  87. package/dist/esm/views/ThemeDebug.js +2 -2
  88. package/dist/esm/views/ThemeDebug.js.map +1 -1
  89. package/package.json +9 -9
  90. package/src/constants/constants.ts +15 -11
  91. package/src/createComponent.tsx +142 -140
  92. package/src/createTamagui.ts +0 -1
  93. package/src/helpers/ThemeManager.tsx +10 -6
  94. package/src/helpers/getSplitStyles.tsx +144 -173
  95. package/src/helpers/getStylesAtomic.ts +7 -7
  96. package/src/helpers/getVariantExtras.tsx +15 -31
  97. package/src/helpers/isTamaguiComponent.tsx +3 -3
  98. package/src/helpers/mergeProps.ts +5 -20
  99. package/src/helpers/normalizeColor.ts +2 -1
  100. package/src/helpers/normalizeValueWithProperty.ts +8 -64
  101. package/src/helpers/{createPropMapper.ts → propMapper.ts} +72 -164
  102. package/src/helpers/pseudoDescriptors.ts +0 -1
  103. package/src/helpers/useShallowSetState.tsx +10 -16
  104. package/src/helpers/withStaticProperties.tsx +13 -0
  105. package/src/hooks/useMedia.tsx +15 -10
  106. package/src/hooks/useStyle.tsx +7 -4
  107. package/src/hooks/useTheme.tsx +36 -47
  108. package/src/index.ts +1 -1
  109. package/src/types.tsx +20 -33
  110. package/src/views/Stack.tsx +1 -4
  111. package/src/views/Theme.tsx +3 -3
  112. package/src/views/ThemeDebug.tsx +2 -2
  113. package/types/constants/constants.d.ts +0 -15
  114. package/types/constants/constants.d.ts.map +1 -1
  115. package/types/createComponent.d.ts +5 -8
  116. package/types/createComponent.d.ts.map +1 -1
  117. package/types/createTamagui.d.ts.map +1 -1
  118. package/types/helpers/ThemeManager.d.ts +1 -1
  119. package/types/helpers/ThemeManager.d.ts.map +1 -1
  120. package/types/helpers/getSplitStyles.d.ts +3 -7
  121. package/types/helpers/getSplitStyles.d.ts.map +1 -1
  122. package/types/helpers/getVariantExtras.d.ts +1 -1
  123. package/types/helpers/getVariantExtras.d.ts.map +1 -1
  124. package/types/helpers/isTamaguiComponent.d.ts.map +1 -1
  125. package/types/helpers/mergeProps.d.ts +1 -1
  126. package/types/helpers/mergeProps.d.ts.map +1 -1
  127. package/types/helpers/normalizeColor.d.ts.map +1 -1
  128. package/types/helpers/normalizeValueWithProperty.d.ts.map +1 -1
  129. package/types/helpers/{createPropMapper.d.ts → propMapper.d.ts} +3 -3
  130. package/types/helpers/propMapper.d.ts.map +1 -0
  131. package/types/helpers/pseudoDescriptors.d.ts.map +1 -1
  132. package/types/helpers/useShallowSetState.d.ts.map +1 -1
  133. package/types/helpers/withStaticProperties.d.ts.map +1 -1
  134. package/types/hooks/useMedia.d.ts.map +1 -1
  135. package/types/hooks/useStyle.d.ts +2 -2
  136. package/types/hooks/useStyle.d.ts.map +1 -1
  137. package/types/hooks/useTheme.d.ts +7 -13
  138. package/types/hooks/useTheme.d.ts.map +1 -1
  139. package/types/index.d.ts +1 -1
  140. package/types/index.d.ts.map +1 -1
  141. package/types/styled.d.ts +1 -1
  142. package/types/types.d.ts +17 -25
  143. package/types/types.d.ts.map +1 -1
  144. package/types/views/Stack.d.ts.map +1 -1
  145. package/dist/cjs/helpers/createPropMapper.js.map +0 -6
  146. package/dist/cjs/helpers/parseStaticConfig.js +0 -40
  147. package/dist/cjs/helpers/parseStaticConfig.js.map +0 -6
  148. package/dist/cjs/helpers/swapFontFaceOnWeight.js +0 -63
  149. package/dist/cjs/helpers/swapFontFaceOnWeight.js.map +0 -6
  150. package/dist/cjs/hooks/useSafeRef.js +0 -59
  151. package/dist/cjs/hooks/useSafeRef.js.map +0 -6
  152. package/dist/cjs/hooks/useServerHooks.js +0 -36
  153. package/dist/cjs/hooks/useServerHooks.js.map +0 -6
  154. package/dist/esm/helpers/createPropMapper.js.map +0 -6
  155. package/dist/esm/helpers/parseStaticConfig.js +0 -16
  156. package/dist/esm/helpers/parseStaticConfig.js.map +0 -6
  157. package/dist/esm/helpers/swapFontFaceOnWeight.js +0 -39
  158. package/dist/esm/helpers/swapFontFaceOnWeight.js.map +0 -6
  159. package/dist/esm/hooks/useSafeRef.js +0 -35
  160. package/dist/esm/hooks/useSafeRef.js.map +0 -6
  161. package/dist/esm/hooks/useServerHooks.js +0 -11
  162. package/dist/esm/hooks/useServerHooks.js.map +0 -6
  163. package/src/helpers/parseStaticConfig.ts +0 -14
  164. package/src/hooks/useSafeRef.ts +0 -45
  165. package/types/helpers/createPropMapper.d.ts.map +0 -1
  166. package/types/helpers/parseStaticConfig.d.ts +0 -3
  167. package/types/helpers/parseStaticConfig.d.ts.map +0 -1
  168. package/types/helpers/swapFontFaceOnWeight.d.ts +0 -4
  169. package/types/helpers/swapFontFaceOnWeight.d.ts.map +0 -1
  170. package/types/hooks/useSafeRef.d.ts +0 -4
  171. package/types/hooks/useSafeRef.d.ts.map +0 -1
  172. package/types/hooks/useServerHooks.d.ts +0 -4
  173. package/types/hooks/useServerHooks.d.ts.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { useComposedRefs } from '@tamagui/compose-refs'
2
2
  import { isClient, isServer, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
3
3
  import { validStyles } from '@tamagui/helpers'
4
+ import { useDidFinishSSR } from '@tamagui/use-did-finish-ssr'
4
5
  import React, {
5
6
  Children,
6
7
  Fragment,
@@ -21,7 +22,6 @@ import { TextAncestorContext } from './contexts/TextAncestorContext'
21
22
  import { didGetVariableValue, setDidGetVariableValue } from './createVariable'
22
23
  import { useSplitStyles } from './helpers/getSplitStyles'
23
24
  import { mergeProps } from './helpers/mergeProps'
24
- import { parseStaticConfig } from './helpers/parseStaticConfig'
25
25
  import { proxyThemeVariables } from './helpers/proxyThemeVariables'
26
26
  import { themeable } from './helpers/themeable'
27
27
  import { useShallowSetState } from './helpers/useShallowSetState'
@@ -35,7 +35,6 @@ import {
35
35
  SpaceValue,
36
36
  SpacerProps,
37
37
  StaticConfig,
38
- StaticConfigParsed,
39
38
  TamaguiComponent,
40
39
  TamaguiComponentEvents,
41
40
  TamaguiComponentState,
@@ -48,17 +47,7 @@ import { Slot } from './views/Slot'
48
47
  import { useThemedChildren } from './views/Theme'
49
48
  import { ThemeDebug } from './views/ThemeDebug'
50
49
 
51
- // let t
52
- // import { timer } from '@tamagui/timer'
53
- // if (true || process.env.ANALYZE) {
54
- // t = require().timer()
55
- // setTimeout(() => {
56
- // const out = t.print()
57
- // if (isClient) {
58
- // alert(out)
59
- // }
60
- // }, 2000)
61
- // }
50
+ // const timer = require('@tamagui/timer').timer()
62
51
 
63
52
  // this appears to fix expo / babel not picking this up sometimes? really odd
64
53
  process.env.TAMAGUI_TARGET
@@ -118,9 +107,7 @@ export function createComponent<
118
107
  ComponentPropTypes extends Object = {},
119
108
  Ref = TamaguiElement,
120
109
  BaseProps = never
121
- >(staticConfigIn: Partial<StaticConfig> | StaticConfigParsed) {
122
- const staticConfig = parseStaticConfig(staticConfigIn)
123
-
110
+ >(staticConfig: StaticConfig) {
124
111
  onConfiguredOnce((conf) => {
125
112
  // one time only setup
126
113
  if (!tamaguiConfig) {
@@ -151,18 +138,22 @@ export function createComponent<
151
138
  const defaultComponentClassName = `is_${staticConfig.componentName}`
152
139
  const defaultProps = staticConfig.defaultProps
153
140
 
154
- if (process.env.NODE_ENV === 'development' && staticConfigIn.defaultProps?.['debug']) {
141
+ if (process.env.NODE_ENV === 'development' && staticConfig.defaultProps?.['debug']) {
155
142
  if (process.env.IS_STATIC !== 'is_static') {
156
143
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
157
144
  console.log(`🐛 [${staticConfig.componentName || 'Component'}]`, {
158
145
  staticConfig,
159
146
  defaultProps,
160
- defaultPropsKeyOrder: Object.keys(defaultProps),
147
+ defaultPropsKeyOrder: defaultProps ? Object.keys(defaultProps) : [],
161
148
  })
162
149
  }
163
150
  }
164
151
 
165
152
  const component = forwardRef<Ref, ComponentPropTypes>((propsIn: any, forwardedRef) => {
153
+ // const shouldTime = staticConfig.defaultProps?.padding === 5
154
+ // let time: any
155
+ // if (shouldTime) time = timer.start()
156
+
166
157
  if (process.env.TAMAGUI_TARGET === 'native') {
167
158
  // todo this could be moved to a cleaner location
168
159
  if (!hasSetupBaseViews) {
@@ -182,7 +173,6 @@ export function createComponent<
182
173
  propsIn['data-test-renders']['current'] += 1
183
174
  }
184
175
  }
185
- // const time = t.start({ quiet: true })
186
176
 
187
177
  // set variants through context
188
178
  // order is after default props but before props
@@ -197,8 +187,8 @@ export function createComponent<
197
187
  // because its after default props but before props this annoying amount of checks
198
188
  propsIn[key] ||
199
189
  propsIn[inverseShorthands[key]] ||
200
- defaultProps[key] ||
201
- defaultProps[inverseShorthands[key]]
190
+ defaultProps?.[key] ||
191
+ defaultProps?.[inverseShorthands[key]]
202
192
  // if not set, use context
203
193
  if (propVal === undefined) {
204
194
  if (contextValue) {
@@ -225,9 +215,8 @@ export function createComponent<
225
215
  // React inserts default props after your props for some reason...
226
216
  // order important so we do loops, you can't just spread because JS does weird things
227
217
  let props: any
228
-
229
218
  if (curDefaultProps) {
230
- props = mergeProps(curDefaultProps, propsIn)[0]
219
+ props = mergeProps(curDefaultProps, propsIn)
231
220
  } else {
232
221
  props = propsIn
233
222
  }
@@ -235,6 +224,8 @@ export function createComponent<
235
224
  const debugProp = props['debug'] as DebugProp
236
225
  const componentName = props.componentName || staticConfig.componentName
237
226
 
227
+ const isHydrated = useDidFinishSSR()
228
+
238
229
  // conditional but if ever true stays true
239
230
  // [animated, inversed]
240
231
  const stateRef = useRef(
@@ -246,6 +237,8 @@ export function createComponent<
246
237
  )
247
238
  stateRef.current ||= {}
248
239
 
240
+ // if (shouldTime) time`stateref`
241
+
249
242
  const hostRef = useRef<TamaguiElement>(null)
250
243
 
251
244
  /**
@@ -259,8 +252,11 @@ export function createComponent<
259
252
  props.animation || (props.style && hasAnimatedStyleValue(props.style))
260
253
  )
261
254
 
255
+ // disable for now still ssr issues
256
+ const supportsCSSVars = animationsConfig?.supportsCSSVars
257
+
262
258
  const willBeAnimated = (() => {
263
- if (isServer) return false
259
+ if (isServer && !supportsCSSVars) return false
264
260
  const curState = stateRef.current
265
261
  const next = !!(hasAnimationProp && !isHOC && useAnimations)
266
262
  return Boolean(next || curState.hasAnimated)
@@ -270,19 +266,16 @@ export function createComponent<
270
266
  const presence = (willBeAnimated && usePresence?.()) || null
271
267
 
272
268
  const hasEnterStyle = !!props.enterStyle
269
+ const needsMount = Boolean((isWeb ? isClient : true) && willBeAnimated)
273
270
 
274
- // disable for now still ssr issues
275
- const supportsCSSVariables = false // ?? animationsConfig?.supportsCSSVariables
276
-
277
- const needsMount = Boolean(
278
- (isWeb ? willBeAnimated && isClient : true) && willBeAnimated
279
- )
271
+ // if (shouldTime) time`pre-use-state`
280
272
 
281
- const initialState = needsMount
282
- ? supportsCSSVariables
273
+ const initialState = willBeAnimated
274
+ ? supportsCSSVars
283
275
  ? defaultComponentStateShouldEnter!
284
276
  : defaultComponentState!
285
277
  : defaultComponentStateMounted!
278
+
286
279
  const states = useState<TamaguiComponentState>(initialState)
287
280
 
288
281
  const state = propsIn.forceStyle
@@ -293,26 +286,23 @@ export function createComponent<
293
286
  // TODO performance optimization could avoid useCallback and just have this be setStateShallow(setState, state) at call-sites
294
287
  const setStateShallow = useShallowSetState(setState, debugProp, componentName)
295
288
 
289
+ // if (shouldTime) time`use-state`
290
+
296
291
  let isAnimated = willBeAnimated
297
292
 
298
- if (willBeAnimated && !supportsCSSVariables) {
299
- // cheat code to not always pay the cost of triple rendering,
300
- // after a bit we consider this component hydrated
301
- let hasHydrated = false
302
- numRenderedOfType[componentName] ??= 0
303
- if (willBeAnimated) {
304
- if (++numRenderedOfType[componentName] > HYDRATION_CUTOFF) {
305
- hasHydrated = true
306
- }
307
- }
308
- const hasPresenceIsHydrated = presence && hasHydrated
309
- if (!hasPresenceIsHydrated) {
310
- if (isAnimated && (isServer || state.unmounted === true)) {
293
+ if (willBeAnimated && !supportsCSSVars) {
294
+ if (!presence && isHydrated) {
295
+ if (isServer || state.unmounted === true) {
311
296
  isAnimated = false
312
297
  }
313
298
  }
314
299
  }
315
300
 
301
+ // once animated, always animated to preserve hooks
302
+ if (willBeAnimated && !stateRef.current.hasAnimated) {
303
+ stateRef.current.hasAnimated = true
304
+ }
305
+
316
306
  const componentClassName = props.asChild
317
307
  ? ''
318
308
  : props.componentName
@@ -322,6 +312,8 @@ export function createComponent<
322
312
  const languageContext = useContext(FontLanguageContext)
323
313
  const isDisabled = props.disabled ?? props.accessibilityState?.disabled
324
314
 
315
+ // if (shouldTime) time`use-context`
316
+
325
317
  const isTaggable = !Component || typeof Component === 'string'
326
318
  // default to tag, fallback to component (when both strings)
327
319
  const element = isWeb ? (isTaggable ? props.tag || Component : Component) : Component
@@ -366,6 +358,8 @@ export function createComponent<
366
358
  const disableThemeProp = props['data-disable-theme']
367
359
  const disableTheme = (disableThemeProp && !willBeAnimated) || isHOC
368
360
 
361
+ // if (shouldTime) time`theme-props`
362
+
369
363
  const themeStateProps = {
370
364
  name: props.theme,
371
365
  componentName,
@@ -405,17 +399,21 @@ export function createComponent<
405
399
  )
406
400
  // prettier-ignore
407
401
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
408
- console.log({ props, state, staticConfig, elementType, themeStateProps, styledContext: { contextProps: styledContextProps, overriddenContextProps }, presence, isAnimated, isHOC, hasAnimationProp, useAnimations, propsInOrder: Object.keys(propsIn), propsOrder: Object.keys(props), curDefaultPropsOrder: Object.keys(curDefaultProps) })
402
+ console.log({ props, state, staticConfig, elementType, themeStateProps, styledContext: { contextProps: styledContextProps, overriddenContextProps }, presence, isAnimated, isHOC, hasAnimationProp, useAnimations, propsInOrder: Object.keys(propsIn), propsOrder: Object.keys(props) })
409
403
  console.groupEnd()
410
404
  }
411
405
  }
412
406
  }
413
407
 
414
- const themeState = useThemeWithState(themeStateProps)!
408
+ // if (shouldTime) time`pre-theme-media`
409
+
410
+ const [themeState, theme] = useThemeWithState(themeStateProps)
415
411
 
416
412
  elementType = Component || elementType
417
413
  const isStringElement = typeof elementType === 'string'
418
414
 
415
+ // if (shouldTime) time`theme`
416
+
419
417
  const mediaState = useMedia(
420
418
  // @ts-ignore, we just pass a stable object so we can get it later with
421
419
  // should match to the one used in `setMediaShouldUpdate` below
@@ -423,6 +421,8 @@ export function createComponent<
423
421
  debugProp ? { props, staticConfig } : null
424
422
  )
425
423
 
424
+ // if (shouldTime) time`media`
425
+
426
426
  setDidGetVariableValue(false)
427
427
 
428
428
  const resolveVariablesAs =
@@ -434,26 +434,31 @@ export function createComponent<
434
434
  // temp: once we fix above we can disable this
435
435
  const keepStyleSSR = willBeAnimated && animationsConfig?.keepStyleSSR
436
436
 
437
+ const styleProps = {
438
+ mediaState,
439
+ noClassNames,
440
+ hasTextAncestor,
441
+ resolveVariablesAs,
442
+ isExiting,
443
+ isAnimated,
444
+ keepStyleSSR,
445
+ } as const
446
+
437
447
  const splitStyles = useSplitStyles(
438
448
  props,
439
449
  staticConfig,
440
- themeState,
441
- {
442
- ...state,
443
- mediaState,
444
- noClassNames,
445
- hasTextAncestor,
446
- resolveVariablesAs,
447
- isExiting,
448
- isAnimated,
449
- keepStyleSSR,
450
- },
450
+ theme,
451
+ themeState.state.name,
452
+ state,
453
+ styleProps,
451
454
  null,
452
455
  languageContext || undefined,
453
456
  elementType,
454
457
  debugProp
455
458
  )
456
459
 
460
+ // if (shouldTime) time`split-styles`
461
+
457
462
  stateRef.current.isListeningToTheme = splitStyles.dynamicThemeAccess
458
463
 
459
464
  // only listen for changes if we are using raw theme values or media space, or dynamic media (native)
@@ -523,21 +528,17 @@ export function createComponent<
523
528
  style: splitStylesStyle,
524
529
  // style: splitStylesStyle,
525
530
  presence,
526
- state: {
527
- ...state,
528
- isAnimated,
529
- },
530
- theme: themeState.theme,
531
+ componentState: state,
532
+ styleProps,
533
+ theme: themeState.state.theme!,
531
534
  pseudos: pseudos || null,
532
535
  onDidAnimate: props.onDidAnimate,
533
536
  hostRef,
534
537
  staticConfig,
535
538
  })
536
539
 
537
- if (isAnimated) {
538
- if (animations) {
539
- animationStyles = animations.style
540
- }
540
+ if (isAnimated && animations) {
541
+ animationStyles = animations.style
541
542
  }
542
543
  }
543
544
 
@@ -569,6 +570,8 @@ export function createComponent<
569
570
  ...nonTamaguiProps
570
571
  } = viewPropsIn
571
572
 
573
+ // if (shouldTime) time`destructure`
574
+
572
575
  const disabled = props.accessibilityState?.disabled || props.accessibilityDisabled
573
576
 
574
577
  // these can ultimately be for DOM, react-native-web views, or animated views
@@ -594,7 +597,7 @@ export function createComponent<
594
597
  viewProps.ref = useComposedRefs(hostRef as any, forwardedRef)
595
598
 
596
599
  if (process.env.NODE_ENV === 'development') {
597
- if (!isText && isWeb && !isHOC) {
600
+ if (!isReactNative && !isText && isWeb && !isHOC) {
598
601
  Children.toArray(props.children).forEach((item) => {
599
602
  // allow newlines because why not its annoying with mdx
600
603
  if (typeof item === 'string' && item !== '\n') {
@@ -606,22 +609,19 @@ export function createComponent<
606
609
  }
607
610
  }
608
611
 
612
+ // if (shouldTime) time`events-hooks`
613
+
609
614
  const unPress = useCallback(() => {
610
615
  setStateShallow({
611
616
  press: false,
612
617
  pressIn: false,
613
618
  })
614
- }, [setStateShallow])
619
+ }, [])
615
620
 
616
621
  const shouldSetMounted = needsMount && state.unmounted
617
622
 
618
623
  // combined multiple effects into one for performance so be careful with logic
619
624
  useIsomorphicLayoutEffect(() => {
620
- // once animated, always animated to preserve hooks
621
- if (willBeAnimated && !stateRef.current.hasAnimated) {
622
- stateRef.current.hasAnimated = true
623
- }
624
-
625
625
  if (shouldSetMounted) {
626
626
  const unmounted =
627
627
  state.unmounted === true && hasEnterStyle ? 'should-enter' : false
@@ -637,50 +637,31 @@ export function createComponent<
637
637
  }
638
638
  }, [shouldSetMounted, state.unmounted])
639
639
 
640
- let styles: Record<string, any>[] | undefined
641
- const avoidStyle = keepStyleSSR && state.unmounted === true
642
-
643
- if (!avoidStyle) {
644
- if (isStringElement && shouldAvoidClasses && !shouldForcePseudo) {
645
- styles = {
646
- ...(animationStyles ?? splitStylesStyle),
647
- }
648
- } else {
649
- styles = [animationStyles ?? splitStylesStyle]
650
-
651
- // ugly but for now...
652
- if (shouldForcePseudo) {
653
- const next = {}
654
- styles.forEach((style) => Object.assign(next, style))
655
- // @ts-ignore
656
- Object.assign(splitStyles.style, next)
657
- }
658
- }
659
- }
640
+ const avoidAnimationStyle = keepStyleSSR && state.unmounted === true
660
641
 
661
642
  let fontFamily = isText
662
- ? splitStyles.fontFamily || staticConfig.defaultProps.fontFamily
643
+ ? splitStyles.fontFamily || staticConfig.defaultProps?.fontFamily
663
644
  : null
664
645
  if (fontFamily && fontFamily[0] === '$') {
665
646
  fontFamily = fontFamily.slice(1)
666
647
  }
667
648
  const fontFamilyClassName = fontFamily ? `font_${fontFamily}` : ''
668
649
 
669
- const classList = [
670
- hasEnterStyle && ((state.unmounted && needsMount) || !isClient)
671
- ? 't_will-mount'
672
- : '',
673
- componentName ? componentClassName : '',
674
- fontFamilyClassName,
675
- classNames ? Object.values(classNames).join(' ') : '',
676
- ]
650
+ const style = avoidAnimationStyle
651
+ ? splitStyles.style
652
+ : animationStyles || splitStyles.style
677
653
 
678
- const className = classList.join(' ')
654
+ let className: string | undefined
679
655
 
680
656
  if (process.env.TAMAGUI_TARGET === 'web') {
681
- const style = avoidStyle ? null : animationStyles ?? splitStyles.style
682
-
683
- if (isAnimatedReactNativeWeb && !avoidStyle) {
657
+ const classList = [
658
+ componentName ? componentClassName : '',
659
+ fontFamilyClassName,
660
+ classNames ? Object.values(classNames).join(' ') : '',
661
+ ]
662
+ className = classList.join(' ')
663
+
664
+ if (isAnimatedReactNativeWeb && !avoidAnimationStyle) {
684
665
  viewProps.style = style
685
666
  } else if (isReactNative) {
686
667
  // TODO these shouldn't really return from getSplitStyles when in Native mode
@@ -689,9 +670,14 @@ export function createComponent<
689
670
  cnStyles[name] = name
690
671
  }
691
672
  viewProps.style = [...(Array.isArray(style) ? style : [style]), cnStyles]
673
+ } else {
674
+ viewProps.className = className
675
+ viewProps.style = style
676
+ }
692
677
 
678
+ // turn debug data- props into dataSet in dev mode
679
+ if (isReactNative) {
693
680
  if (process.env.NODE_ENV === 'development') {
694
- // turn debug data- props into dataSet in dev mode
695
681
  Object.keys(viewProps).forEach((key) => {
696
682
  if (key.startsWith('data-')) {
697
683
  viewProps.dataSet ??= {}
@@ -700,13 +686,10 @@ export function createComponent<
700
686
  }
701
687
  })
702
688
  }
703
- } else {
704
- viewProps.className = className
705
- viewProps.style = style
706
689
  }
707
690
  } else {
708
691
  // native assign styles
709
- viewProps.style = styles
692
+ viewProps.style = style
710
693
  }
711
694
 
712
695
  const runtimePressStyle = !disabled && noClassNames && pseudos?.pressStyle
@@ -729,6 +712,8 @@ export function createComponent<
729
712
  (isWeb && noClassNames && 'hoverStyle' in props)
730
713
  )
731
714
 
715
+ // if (shouldTime) time`events-setup`
716
+
732
717
  const events: TamaguiComponentEvents | null =
733
718
  shouldAttach && !isDisabled && !asChild
734
719
  ? {
@@ -795,22 +780,22 @@ export function createComponent<
795
780
  }
796
781
  : null
797
782
 
798
- if (process.env.TAMAGUI_TARGET === 'native') {
799
- if (events) {
800
- // replicating TouchableWithoutFeedback
801
- Object.assign(events, {
802
- cancelable: !props.rejectResponderTermination,
803
- disabled: isDisabled,
804
- hitSlop: props.hitSlop,
805
- delayLongPress: props.delayLongPress,
806
- delayPressIn: props.delayPressIn,
807
- delayPressOut: props.delayPressOut,
808
- focusable: viewProps.focusable ?? true,
809
- minPressDuration: 0,
810
- })
811
- }
783
+ if (process.env.TAMAGUI_TARGET === 'native' && events) {
784
+ // replicating TouchableWithoutFeedback
785
+ Object.assign(events, {
786
+ cancelable: !viewProps.rejectResponderTermination,
787
+ disabled: isDisabled,
788
+ hitSlop: viewProps.hitSlop,
789
+ delayLongPress: viewProps.delayLongPress,
790
+ delayPressIn: viewProps.delayPressIn,
791
+ delayPressOut: viewProps.delayPressOut,
792
+ focusable: viewProps.focusable ?? true,
793
+ minPressDuration: 0,
794
+ })
812
795
  }
813
796
 
797
+ // if (shouldTime) time`events`
798
+
814
799
  if (process.env.NODE_ENV === 'development' && debugProp === 'verbose') {
815
800
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
816
801
  console.log(`events`, { events, isHoverable, attachPress })
@@ -826,6 +811,8 @@ export function createComponent<
826
811
 
827
812
  const direction = props.spaceDirection || 'both'
828
813
 
814
+ // if (shouldTime) time`hooks`
815
+
829
816
  // since we re-render without changing children often for animations or on mount
830
817
  // we memo children here. tested this on the site homepage which has hundreds of components
831
818
  // and i see no difference in startup performance, but i do see it memoing often
@@ -843,13 +830,12 @@ export function createComponent<
843
830
 
844
831
  if (asChild) {
845
832
  elementType = Slot
846
- viewProps = {
847
- ...viewProps,
833
+ Object.assign(viewProps, {
848
834
  onPress,
849
835
  onLongPress,
850
836
  onPressIn,
851
837
  onPressOut,
852
- }
838
+ })
853
839
  }
854
840
 
855
841
  content = createElement(elementType, viewProps, content)
@@ -862,14 +848,12 @@ export function createComponent<
862
848
  // passPropsToChildren: true,
863
849
  })
864
850
 
865
- if (process.env.NODE_ENV === 'development') {
866
- if (props['debug'] === 'visualize') {
867
- content = (
868
- <ThemeDebug themeState={themeState} themeProps={props}>
869
- {content}
870
- </ThemeDebug>
871
- )
872
- }
851
+ if (process.env.NODE_ENV === 'development' && props['debug'] === 'visualize') {
852
+ content = (
853
+ <ThemeDebug themeState={themeState} themeProps={props}>
854
+ {content}
855
+ </ThemeDebug>
856
+ )
873
857
  }
874
858
 
875
859
  if (process.env.TAMAGUI_TARGET === 'web') {
@@ -901,7 +885,11 @@ export function createComponent<
901
885
  if (process.env.NODE_ENV === 'development') {
902
886
  if (debugProp) {
903
887
  const element = typeof elementType === 'string' ? elementType : 'Component'
904
- console.groupCollapsed(`render <${element} /> with props`)
888
+ console.groupCollapsed(
889
+ `render <${element} /> with props`,
890
+ initialState,
891
+ willBeAnimated
892
+ )
905
893
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
906
894
  console.log('viewProps', viewProps)
907
895
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
@@ -915,16 +903,28 @@ export function createComponent<
915
903
  if (typeof window !== 'undefined') {
916
904
  // prettier-ignore
917
905
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
918
- console.log({ state, themeState, isAnimated, isAnimatedReactNativeWeb, defaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: props.className?.split(' '), classNamesOut: viewProps.className?.split(' '), events, shouldAttach, styles, pseudos, content, shouldAvoidClasses, avoidClasses: avoidClassesWhileAnimating, animation: props.animation, style: splitStylesStyle, staticConfig, tamaguiConfig, shouldForcePseudo })
906
+ console.log({ state, themeState, isAnimated, isAnimatedReactNativeWeb, defaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: props.className?.split(' '), classNamesOut: viewProps.className?.split(' '), events, shouldAttach, pseudos, content, shouldAvoidClasses, avoidClasses: avoidClassesWhileAnimating, animation: props.animation, style: splitStylesStyle, staticConfig, tamaguiConfig, shouldForcePseudo, elementType, initialState })
919
907
  }
920
908
  console.groupEnd()
921
909
  console.groupEnd()
922
910
  }
923
911
  }
924
912
 
913
+ // if (shouldTime) {
914
+ // time`rest`
915
+ // setTimeout(() => {
916
+ // if (!hasLogged) {
917
+ // timer.print()
918
+ // }
919
+ // hasLogged = true
920
+ // }, 1000)
921
+ // }
922
+
925
923
  return content
926
924
  })
927
925
 
926
+ // let hasLogged = false
927
+
928
928
  if (staticConfig.componentName) {
929
929
  component.displayName = staticConfig.componentName
930
930
  }
@@ -973,7 +973,9 @@ export function createComponent<
973
973
  }
974
974
 
975
975
  // for elements to avoid spacing
976
- export const Unspaced = (props: { children?: any }) => props.children
976
+ export function Unspaced(props: { children?: any }) {
977
+ return props.children
978
+ }
977
979
  Unspaced['isUnspaced'] = true
978
980
 
979
981
  // dont used styled() here to avoid circular deps
@@ -251,7 +251,6 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
251
251
  }
252
252
 
253
253
  const designSystem = `._ovs-contain {overscroll-behavior:contain;}
254
- .t_unmounted .t_will-mount {opacity:0;visibility:hidden;}
255
254
  .is_Text .is_Text {display:inline-flex;}
256
255
  ._dsp_contents {display:contents;}
257
256
  ${themeConfig.cssRuleSets.join(separator)}`
@@ -28,7 +28,7 @@ export type ThemeManagerState = {
28
28
  const emptyState: ThemeManagerState = { name: '' }
29
29
 
30
30
  export function getHasThemeUpdatingProps(props: ThemeProps) {
31
- return props.name || props.componentName || props.inverse || props.reset
31
+ return Boolean(props.name || props.componentName || props.inverse || props.reset)
32
32
  }
33
33
 
34
34
  let uid = 0
@@ -139,10 +139,10 @@ export class ThemeManager {
139
139
  }
140
140
 
141
141
  getState(props = this.props, parentManager = this.parentManager) {
142
- return (
142
+ const next =
143
143
  getState(props, parentManager) ||
144
144
  (process.env.TAMAGUI_TARGET === 'native' ? parentManager?.state || null : null)
145
- )
145
+ return next
146
146
  }
147
147
 
148
148
  _allKeys: Set<string> | null = null
@@ -155,9 +155,9 @@ export class ThemeManager {
155
155
  }
156
156
 
157
157
  // gets value going up to parents
158
- getValue(key: string, state?: ThemeManagerState) {
158
+ getValue(key: string, state: ThemeManagerState = this.state) {
159
159
  if (!key) return
160
- let theme = (state || this.state).theme
160
+ let theme = state.theme
161
161
  let manager = this as ThemeManager | null
162
162
  while (theme && manager) {
163
163
  if (key in theme) {
@@ -334,7 +334,11 @@ function getState(
334
334
  }
335
335
  }
336
336
 
337
- if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {
337
+ if (
338
+ process.env.NODE_ENV === 'development' &&
339
+ typeof props.debug === 'string' &&
340
+ typeof window !== 'undefined'
341
+ ) {
338
342
  console.warn('ThemeManager.getState():', {
339
343
  result,
340
344
  })