@tamagui/core 1.0.1-beta.220 → 1.0.1-beta.221

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 (284) hide show
  1. package/dist/cjs/addTheme.js +7 -10
  2. package/dist/cjs/addTheme.js.map +3 -3
  3. package/dist/cjs/config.js +8 -4
  4. package/dist/cjs/config.js.map +2 -2
  5. package/dist/cjs/{hooks/useUnmountEffect.js → contexts/ButtonNestingContext.js} +7 -9
  6. package/dist/cjs/contexts/ButtonNestingContext.js.map +7 -0
  7. package/dist/cjs/createComponent.js +63 -67
  8. package/dist/cjs/createComponent.js.map +3 -3
  9. package/dist/cjs/createTamagui.js +13 -12
  10. package/dist/cjs/createTamagui.js.map +2 -2
  11. package/dist/cjs/createTokens.js.map +2 -2
  12. package/dist/cjs/createTokens.test.js +27 -0
  13. package/dist/cjs/createTokens.test.js.map +7 -0
  14. package/dist/cjs/createVariable.js +4 -9
  15. package/dist/cjs/createVariable.js.map +2 -2
  16. package/dist/cjs/createVariable.test.js +7 -0
  17. package/dist/cjs/createVariable.test.js.map +7 -0
  18. package/dist/cjs/createVariables.js +6 -7
  19. package/dist/cjs/createVariables.js.map +2 -2
  20. package/dist/cjs/helpers/ThemeManager.js +161 -147
  21. package/dist/cjs/helpers/ThemeManager.js.map +3 -3
  22. package/dist/cjs/helpers/ThemeManager.test.js +421 -34
  23. package/dist/cjs/helpers/ThemeManager.test.js.map +2 -2
  24. package/dist/cjs/helpers/{getTokens.js → ThemeManagerContext.js} +8 -8
  25. package/dist/cjs/helpers/ThemeManagerContext.js.map +7 -0
  26. package/dist/cjs/helpers/createPropMapper.js +4 -4
  27. package/dist/cjs/helpers/createPropMapper.js.map +2 -2
  28. package/dist/cjs/helpers/extendStaticConfig.js +2 -4
  29. package/dist/cjs/helpers/extendStaticConfig.js.map +2 -2
  30. package/dist/cjs/helpers/{assignNativePropsToWeb.native.js → getBoundingClientRect.js} +15 -8
  31. package/dist/cjs/helpers/getBoundingClientRect.js.map +7 -0
  32. package/dist/cjs/{hooks/useConstant.js → helpers/getRect.js} +14 -17
  33. package/dist/cjs/helpers/getRect.js.map +7 -0
  34. package/dist/cjs/helpers/getSplitStyles.js +82 -85
  35. package/dist/cjs/helpers/getSplitStyles.js.map +3 -3
  36. package/dist/cjs/helpers/getThemeCSSRules.js +6 -2
  37. package/dist/cjs/helpers/getThemeCSSRules.js.map +2 -2
  38. package/dist/cjs/helpers/insertStyleRule.js +1 -1
  39. package/dist/cjs/helpers/insertStyleRule.js.map +2 -2
  40. package/dist/cjs/helpers/mergeTransform.js +11 -8
  41. package/dist/cjs/helpers/mergeTransform.js.map +2 -2
  42. package/dist/cjs/helpers/pseudoDescriptors.js +1 -0
  43. package/dist/cjs/helpers/pseudoDescriptors.js.map +2 -2
  44. package/dist/cjs/helpers/themeable.js +9 -9
  45. package/dist/cjs/helpers/themeable.js.map +2 -2
  46. package/dist/cjs/hooks/useElementLayout.js +4 -12
  47. package/dist/cjs/hooks/useElementLayout.js.map +2 -2
  48. package/dist/cjs/hooks/useMedia.js +2 -1
  49. package/dist/cjs/hooks/useMedia.js.map +2 -2
  50. package/dist/cjs/hooks/useTheme.js +114 -156
  51. package/dist/cjs/hooks/useTheme.js.map +3 -3
  52. package/dist/cjs/hooks/{useIsMounted.js → useThemeName.js} +23 -14
  53. package/dist/cjs/hooks/useThemeName.js.map +7 -0
  54. package/dist/cjs/index.js +2 -5
  55. package/dist/cjs/index.js.map +2 -2
  56. package/dist/cjs/setupReactNative.js +20 -7
  57. package/dist/cjs/setupReactNative.js.map +2 -2
  58. package/dist/cjs/styled.js +2 -19
  59. package/dist/cjs/styled.js.map +2 -2
  60. package/dist/cjs/types.js.map +1 -1
  61. package/dist/cjs/updateTheme.js +9 -9
  62. package/dist/cjs/updateTheme.js.map +2 -2
  63. package/dist/cjs/views/TamaguiProvider.js +3 -3
  64. package/dist/cjs/views/TamaguiProvider.js.map +2 -2
  65. package/dist/cjs/views/Theme.js +39 -28
  66. package/dist/cjs/views/Theme.js.map +3 -3
  67. package/dist/cjs/views/ThemeProvider.js +8 -33
  68. package/dist/cjs/views/ThemeProvider.js.map +3 -3
  69. package/dist/esm/addTheme.js +7 -10
  70. package/dist/esm/addTheme.js.map +3 -3
  71. package/dist/esm/config.js +8 -3
  72. package/dist/esm/config.js.map +2 -2
  73. package/dist/esm/contexts/ButtonNestingContext.js +6 -0
  74. package/dist/esm/contexts/ButtonNestingContext.js.map +7 -0
  75. package/dist/esm/createComponent.js +65 -70
  76. package/dist/esm/createComponent.js.map +3 -3
  77. package/dist/esm/createTamagui.js +13 -12
  78. package/dist/esm/createTamagui.js.map +2 -2
  79. package/dist/esm/createTokens.js.map +2 -2
  80. package/dist/esm/createTokens.test.js +26 -0
  81. package/dist/esm/createTokens.test.js.map +7 -0
  82. package/dist/esm/createVariable.js +4 -9
  83. package/dist/esm/createVariable.js.map +2 -2
  84. package/dist/esm/createVariable.test.js +6 -0
  85. package/dist/esm/createVariable.test.js.map +7 -0
  86. package/dist/esm/createVariables.js +6 -7
  87. package/dist/esm/createVariables.js.map +2 -2
  88. package/dist/esm/helpers/ThemeManager.js +140 -144
  89. package/dist/esm/helpers/ThemeManager.js.map +3 -3
  90. package/dist/esm/helpers/ThemeManager.test.js +421 -34
  91. package/dist/esm/helpers/ThemeManager.test.js.map +2 -2
  92. package/dist/esm/helpers/ThemeManagerContext.js +6 -0
  93. package/dist/esm/helpers/ThemeManagerContext.js.map +7 -0
  94. package/dist/esm/helpers/createPropMapper.js +4 -4
  95. package/dist/esm/helpers/createPropMapper.js.map +2 -2
  96. package/dist/esm/helpers/extendStaticConfig.js +2 -4
  97. package/dist/esm/helpers/extendStaticConfig.js.map +2 -2
  98. package/dist/esm/helpers/getBoundingClientRect.js +13 -0
  99. package/dist/esm/helpers/getBoundingClientRect.js.map +7 -0
  100. package/dist/esm/helpers/getRect.js +12 -0
  101. package/dist/esm/helpers/getRect.js.map +7 -0
  102. package/dist/esm/helpers/getSplitStyles.js +90 -87
  103. package/dist/esm/helpers/getSplitStyles.js.map +3 -3
  104. package/dist/esm/helpers/getThemeCSSRules.js +6 -2
  105. package/dist/esm/helpers/getThemeCSSRules.js.map +2 -2
  106. package/dist/esm/helpers/insertStyleRule.js +1 -1
  107. package/dist/esm/helpers/insertStyleRule.js.map +2 -2
  108. package/dist/esm/helpers/mergeTransform.js +8 -6
  109. package/dist/esm/helpers/mergeTransform.js.map +2 -2
  110. package/dist/esm/helpers/pseudoDescriptors.js +1 -0
  111. package/dist/esm/helpers/pseudoDescriptors.js.map +2 -2
  112. package/dist/esm/helpers/themeable.js +9 -9
  113. package/dist/esm/helpers/themeable.js.map +2 -2
  114. package/dist/esm/hooks/useElementLayout.js +2 -9
  115. package/dist/esm/hooks/useElementLayout.js.map +2 -2
  116. package/dist/esm/hooks/useMedia.js +3 -2
  117. package/dist/esm/hooks/useMedia.js.map +2 -2
  118. package/dist/esm/hooks/useTheme.js +114 -159
  119. package/dist/esm/hooks/useTheme.js.map +3 -3
  120. package/dist/esm/hooks/useThemeName.js +25 -0
  121. package/dist/esm/hooks/useThemeName.js.map +7 -0
  122. package/dist/esm/index.js +3 -5
  123. package/dist/esm/index.js.map +2 -2
  124. package/dist/esm/setupReactNative.js +18 -6
  125. package/dist/esm/setupReactNative.js.map +2 -2
  126. package/dist/esm/styled.js +3 -20
  127. package/dist/esm/styled.js.map +2 -2
  128. package/dist/esm/updateTheme.js +9 -9
  129. package/dist/esm/updateTheme.js.map +2 -2
  130. package/dist/esm/views/TamaguiProvider.js +4 -4
  131. package/dist/esm/views/TamaguiProvider.js.map +2 -2
  132. package/dist/esm/views/Theme.js +40 -29
  133. package/dist/esm/views/Theme.js.map +3 -3
  134. package/dist/esm/views/ThemeProvider.js +8 -27
  135. package/dist/esm/views/ThemeProvider.js.map +2 -2
  136. package/package.json +12 -12
  137. package/src/__snapshots__/createTokens.test.ts.snap +877 -0
  138. package/src/addTheme.ts +9 -12
  139. package/src/config.ts +10 -2
  140. package/src/contexts/ButtonNestingContext.tsx +3 -0
  141. package/src/createComponent.tsx +117 -108
  142. package/src/createTamagui.ts +16 -14
  143. package/src/createTokens.test.ts +29 -0
  144. package/src/createTokens.ts +1 -1
  145. package/src/createVariable.test.ts +7 -0
  146. package/src/createVariable.ts +4 -10
  147. package/src/createVariables.ts +7 -7
  148. package/src/helpers/ThemeManager.test.tsx +480 -0
  149. package/src/helpers/ThemeManager.tsx +171 -166
  150. package/src/helpers/ThemeManagerContext.tsx +5 -0
  151. package/src/helpers/createPropMapper.ts +4 -4
  152. package/src/helpers/extendStaticConfig.ts +4 -4
  153. package/src/helpers/getBoundingClientRect.tsx +7 -0
  154. package/src/helpers/getRect.tsx +8 -0
  155. package/src/helpers/getSplitStyles.tsx +98 -93
  156. package/src/helpers/getThemeCSSRules.ts +9 -2
  157. package/src/helpers/insertStyleRule.tsx +2 -2
  158. package/src/helpers/mergeTransform.ts +13 -6
  159. package/src/helpers/pseudoDescriptors.ts +1 -0
  160. package/src/helpers/themeable.tsx +17 -9
  161. package/src/hooks/useElementLayout.tsx +3 -8
  162. package/src/hooks/useMedia.tsx +3 -3
  163. package/src/hooks/useTheme.tsx +138 -211
  164. package/src/hooks/useThemeName.tsx +25 -0
  165. package/src/index.ts +3 -4
  166. package/src/setupReactNative.ts +16 -5
  167. package/src/styled.tsx +4 -23
  168. package/src/types.tsx +42 -17
  169. package/src/updateTheme.ts +12 -9
  170. package/src/views/TamaguiProvider.tsx +5 -5
  171. package/src/views/Theme.tsx +48 -39
  172. package/src/views/ThemeProvider.tsx +11 -33
  173. package/types/Tamagui.d.ts +1 -1
  174. package/types/addTheme.d.ts +23 -2
  175. package/types/config.d.ts +0 -1
  176. package/types/contexts/ButtonNestingContext.d.ts +3 -0
  177. package/types/createTokens.test.d.ts +2 -0
  178. package/types/createVariable.d.ts +2 -2
  179. package/types/createVariable.test.d.ts +2 -0
  180. package/types/helpers/ThemeManager.d.ts +20 -30
  181. package/types/helpers/ThemeManager.test.d.ts +2 -0
  182. package/types/helpers/ThemeManagerContext.d.ts +4 -0
  183. package/types/helpers/getBoundingClientRect.d.ts +2 -0
  184. package/types/helpers/getRect.d.ts +9 -0
  185. package/types/helpers/insertStyleRule.d.ts +1 -1
  186. package/types/helpers/mergeTransform.d.ts +5 -3
  187. package/types/helpers/themeable.d.ts +3 -0
  188. package/types/hooks/useElementLayout.d.ts +0 -8
  189. package/types/hooks/useTheme.d.ts +10 -20
  190. package/types/hooks/useThemeName.d.ts +5 -0
  191. package/types/index.d.ts +3 -4
  192. package/types/setupReactNative.d.ts +4 -2
  193. package/types/types.d.ts +35 -10
  194. package/types/updateTheme.d.ts +23 -2
  195. package/types/views/Theme.d.ts +3 -4
  196. package/dist/cjs/constants/platform.js +0 -74
  197. package/dist/cjs/constants/platform.js.map +0 -7
  198. package/dist/cjs/constants/platform.native.js +0 -62
  199. package/dist/cjs/constants/platform.native.js.map +0 -7
  200. package/dist/cjs/helpers/assignNativePropsToWeb.js +0 -188
  201. package/dist/cjs/helpers/assignNativePropsToWeb.js.map +0 -7
  202. package/dist/cjs/helpers/assignNativePropsToWeb.native.js.map +0 -7
  203. package/dist/cjs/helpers/calc.js +0 -71
  204. package/dist/cjs/helpers/calc.js.map +0 -7
  205. package/dist/cjs/helpers/getFont.js +0 -66
  206. package/dist/cjs/helpers/getFont.js.map +0 -7
  207. package/dist/cjs/helpers/getStackSize.js +0 -46
  208. package/dist/cjs/helpers/getStackSize.js.map +0 -7
  209. package/dist/cjs/helpers/getTokens.js.map +0 -7
  210. package/dist/cjs/helpers/startTransition.js +0 -36
  211. package/dist/cjs/helpers/startTransition.js.map +0 -7
  212. package/dist/cjs/helpers/validate.js +0 -2
  213. package/dist/cjs/helpers/validate.js.map +0 -7
  214. package/dist/cjs/hooks/useConstant.js.map +0 -7
  215. package/dist/cjs/hooks/useIsMounted.js.map +0 -7
  216. package/dist/cjs/hooks/usePressable.js +0 -36
  217. package/dist/cjs/hooks/usePressable.js.map +0 -7
  218. package/dist/cjs/hooks/useUnmountEffect.js.map +0 -7
  219. package/dist/cjs/injectStyles.js +0 -40
  220. package/dist/cjs/injectStyles.js.map +0 -7
  221. package/dist/cjs/react-native.js +0 -22
  222. package/dist/cjs/react-native.js.map +0 -7
  223. package/dist/esm/constants/platform.js +0 -39
  224. package/dist/esm/constants/platform.js.map +0 -7
  225. package/dist/esm/constants/platform.native.js +0 -28
  226. package/dist/esm/constants/platform.native.js.map +0 -7
  227. package/dist/esm/helpers/assignNativePropsToWeb.js +0 -164
  228. package/dist/esm/helpers/assignNativePropsToWeb.js.map +0 -7
  229. package/dist/esm/helpers/assignNativePropsToWeb.native.js +0 -6
  230. package/dist/esm/helpers/assignNativePropsToWeb.native.js.map +0 -7
  231. package/dist/esm/helpers/calc.js +0 -47
  232. package/dist/esm/helpers/calc.js.map +0 -7
  233. package/dist/esm/helpers/getFont.js +0 -42
  234. package/dist/esm/helpers/getFont.js.map +0 -7
  235. package/dist/esm/helpers/getStackSize.js +0 -22
  236. package/dist/esm/helpers/getStackSize.js.map +0 -7
  237. package/dist/esm/helpers/getTokens.js +0 -6
  238. package/dist/esm/helpers/getTokens.js.map +0 -7
  239. package/dist/esm/helpers/startTransition.js +0 -6
  240. package/dist/esm/helpers/startTransition.js.map +0 -7
  241. package/dist/esm/helpers/validate.js +0 -1
  242. package/dist/esm/helpers/validate.js.map +0 -7
  243. package/dist/esm/hooks/useConstant.js +0 -15
  244. package/dist/esm/hooks/useConstant.js.map +0 -7
  245. package/dist/esm/hooks/useIsMounted.js +0 -16
  246. package/dist/esm/hooks/useIsMounted.js.map +0 -7
  247. package/dist/esm/hooks/usePressable.js +0 -12
  248. package/dist/esm/hooks/usePressable.js.map +0 -7
  249. package/dist/esm/hooks/useUnmountEffect.js +0 -8
  250. package/dist/esm/hooks/useUnmountEffect.js.map +0 -7
  251. package/dist/esm/injectStyles.js +0 -16
  252. package/dist/esm/injectStyles.js.map +0 -7
  253. package/dist/esm/react-native.js +0 -3
  254. package/dist/esm/react-native.js.map +0 -7
  255. package/src/contexts/ButtonInsideButtonContext.tsx +0 -3
  256. package/src/contexts/ThemeContext.tsx +0 -5
  257. package/src/helpers/areEqualSets.tsx +0 -9
  258. package/src/views/ThemeInverse.tsx +0 -43
  259. package/src/views/ThemeReset.tsx +0 -43
  260. package/types/constants/platform.d.ts +0 -13
  261. package/types/constants/platform.native.d.ts +0 -13
  262. package/types/contexts/ButtonInsideButtonContext.d.ts +0 -3
  263. package/types/contexts/ThemeContext.d.ts +0 -7
  264. package/types/helpers/areEqualSets.d.ts +0 -2
  265. package/types/helpers/assignNativePropsToWeb.d.ts +0 -2
  266. package/types/helpers/assignNativePropsToWeb.native.d.ts +0 -2
  267. package/types/helpers/calc.d.ts +0 -1
  268. package/types/helpers/getFont.d.ts +0 -3
  269. package/types/helpers/getStackSize.d.ts +0 -8
  270. package/types/helpers/getTokens.d.ts +0 -2
  271. package/types/helpers/startTransition.d.ts +0 -3
  272. package/types/helpers/validate.d.ts +0 -1
  273. package/types/hooks/useConstant.d.ts +0 -2
  274. package/types/hooks/useIsMounted.d.ts +0 -3
  275. package/types/hooks/useMedia.test.d.ts +0 -1
  276. package/types/hooks/usePressable.d.ts +0 -3
  277. package/types/hooks/usePressablePressResponder.d.ts +0 -84
  278. package/types/hooks/useUnmountEffect.d.ts +0 -2
  279. package/types/injectStyles.d.ts +0 -7
  280. package/types/react-native.d.ts +0 -8
  281. package/types/views/AbsoluteFill.d.ts +0 -5
  282. package/types/views/AbsoluteFill.native.d.ts +0 -3
  283. package/types/views/ThemeInverse.d.ts +0 -9
  284. package/types/views/ThemeReset.d.ts +0 -4
package/src/addTheme.ts CHANGED
@@ -5,27 +5,25 @@ import { getThemeCSSRules } from './helpers/getThemeCSSRules'
5
5
  import { ensureThemeVariable, proxyThemeToParents } from './helpers/themes'
6
6
  import { ThemeDefinition, ThemeParsed } from './types'
7
7
 
8
- export function addTheme({
9
- name: themeName,
10
- theme: themeIn,
11
- insertCSS,
12
- update,
13
- }: {
8
+ export function addTheme(props: {
14
9
  name: string
15
- theme: ThemeDefinition
10
+ theme: Partial<Record<keyof ThemeDefinition, any>>
16
11
  insertCSS?: boolean
17
12
  update?: boolean
18
13
  }) {
19
14
  const config = getConfig()
15
+
20
16
  if (process.env.NODE_ENV === 'development') {
21
17
  if (!config) {
22
- throw new Error(`Must run createTamagui once before loading theme`)
18
+ throw new Error(`No config`)
23
19
  }
24
- if (!update && config.themes[themeName]) {
25
- throw new Error(`Already defined theme "${themeName}", use updateTheme to change values`)
20
+ const theme = config.themes[props.name]
21
+ if (!props.update && theme) {
22
+ return { theme }
26
23
  }
27
24
  }
28
25
 
26
+ const { name: themeName, theme: themeIn, insertCSS } = props
29
27
  const theme = { ...themeIn } as ThemeParsed
30
28
  for (const key in theme) {
31
29
  ensureThemeVariable(theme, key)
@@ -45,7 +43,7 @@ export function addTheme({
45
43
  names: [themeName],
46
44
  theme,
47
45
  })
48
- const id = `tamagui_theme_style_${themeName}`
46
+ const id = `t_theme_style_${themeName}`
49
47
  const existing = document.querySelector(`#${id}`)
50
48
  const style = document.createElement('style')
51
49
  style.id = id
@@ -60,7 +58,6 @@ export function addTheme({
60
58
  updateConfig('themes', { ...config.themes, [themeName]: themeProxied })
61
59
 
62
60
  // trigger updates in components
63
-
64
61
  return {
65
62
  theme: themeProxied,
66
63
  cssRules,
package/src/config.ts CHANGED
@@ -17,8 +17,16 @@ export const setConfigFont = (name: string, font: any, fontParsed: any) => {
17
17
  Object.assign(conf!.fontsParsed, { [`$${name}`]: fontParsed })
18
18
  }
19
19
 
20
- export const getHasConfigured = () => !!conf
21
- export const getConfig = () => conf!
20
+ export const getConfig = () => {
21
+ if (!conf) {
22
+ throw new Error(
23
+ process.env.NODE_ENV === 'development'
24
+ ? `Missing tamagui config, you either have a duplicate config, or haven't set it up. Be sure createTamagui is called before rendering.`
25
+ : `Err0`
26
+ )
27
+ }
28
+ return conf
29
+ }
22
30
  export const getTokens = (prefixed?: boolean): Tokens =>
23
31
  prefixed ? conf!.tokensParsed : conf!.tokens
24
32
 
@@ -0,0 +1,3 @@
1
+ import { createContext } from 'react'
2
+
3
+ export const ButtonNestingContext = createContext(false)
@@ -1,6 +1,5 @@
1
1
  import { useComposedRefs } from '@tamagui/compose-refs'
2
2
  import { isClient, isRSC, isServer, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
3
- /* eslint-disable react-hooks/rules-of-hooks */
4
3
  import {
5
4
  composeEventHandlers,
6
5
  stylePropsTransform,
@@ -10,7 +9,6 @@ import {
10
9
  } from '@tamagui/helpers'
11
10
  import { useResponderEvents } from '@tamagui/react-native-use-responder-events'
12
11
  import type { ViewStyle } from '@tamagui/types-react-native'
13
- import { useForceUpdate } from '@tamagui/use-force-update'
14
12
  import React, {
15
13
  Children,
16
14
  Fragment,
@@ -29,22 +27,22 @@ import { stackDefaultStyles } from './constants/constants'
29
27
  import { FontLanguageContext } from './contexts/FontLanguageContext'
30
28
  import { TextAncestorContext } from './contexts/TextAncestorContext'
31
29
  import { extendStaticConfig, parseStaticConfig } from './helpers/extendStaticConfig'
30
+ import { getRect } from './helpers/getRect'
32
31
  import { getSubStyle, useSplitStyles } from './helpers/getSplitStyles'
33
32
  import { getAllSelectors } from './helpers/insertStyleRule'
34
33
  import { mergeProps } from './helpers/mergeProps'
35
34
  import { mergeTransform } from './helpers/mergeTransform'
36
35
  import { proxyThemeVariables } from './helpers/proxyThemeVariables'
37
36
  import { useShallowSetState } from './helpers/useShallowSetState'
38
- import { getRect, measureLayout, useElementLayout } from './hooks/useElementLayout'
37
+ import { measureLayout, useElementLayout } from './hooks/useElementLayout'
39
38
  import { addMediaQueryListener, getInitialMediaState } from './hooks/useMedia'
40
39
  import { useServerRef, useServerState } from './hooks/useServerHooks'
41
- import { getThemeManager, useTheme } from './hooks/useTheme'
40
+ import { getThemeIsNewTheme, getThemeManager, useTheme } from './hooks/useTheme'
42
41
  import {
43
42
  DebugProp,
44
43
  SpaceDirection,
45
44
  SpaceTokens,
46
45
  SpacerProps,
47
- SplitStyleState,
48
46
  StaticConfig,
49
47
  StaticConfigParsed,
50
48
  StylableComponent,
@@ -60,7 +58,18 @@ import { usePressability } from './vendor/Pressability'
60
58
  import { Slot, mergeEvent } from './views/Slot'
61
59
  import { wrapThemeManagerContext } from './views/Theme'
62
60
 
63
- React['keep']
61
+ // let t
62
+ // import { timer } from '@tamagui/timer'
63
+ // if (true || process.env.ANALYZE) {
64
+ // t = require().timer()
65
+ // setTimeout(() => {
66
+ // const out = t.print()
67
+ // if (isClient) {
68
+ // alert(out)
69
+ // }
70
+ // }, 2000)
71
+ // }
72
+
64
73
  // this appears to fix expo / babel not picking this up sometimes? really odd
65
74
  process.env.TAMAGUI_TARGET
66
75
 
@@ -105,17 +114,6 @@ if (process.env.TAMAGUI_TARGET === 'native') {
105
114
  BaseView = native.View || native.default.View
106
115
  }
107
116
 
108
- // let t
109
- // if (process.env.ANALYZE) {
110
- // const t = require('@tamagui/timer').timer()
111
- // setTimeout(() => {
112
- // const out = t.print()
113
- // if (isClient) {
114
- // alert(out)
115
- // }
116
- // }, 2000)
117
- // }
118
-
119
117
  export function createComponent<
120
118
  ComponentPropTypes extends Object = {},
121
119
  Ref = TamaguiElement,
@@ -131,7 +129,6 @@ export function createComponent<
131
129
  })()
132
130
 
133
131
  const defaultComponentClassName = `is_${staticConfig.componentName}`
134
- const avoidClassesWhileAnimating = true
135
132
  let defaultNativeStyle: any
136
133
  let tamaguiDefaultProps: any
137
134
  let defaultTag: string | undefined
@@ -163,6 +160,9 @@ export function createComponent<
163
160
  /**
164
161
  * Component state for tracking animations, pseudos
165
162
  */
163
+ const animationsConfig = tamaguiConfig.animations
164
+ const useAnimations = animationsConfig?.useAnimations as UseAnimationHook | undefined
165
+ const avoidClassesWhileAnimating = animationsConfig.isReactNative
166
166
  const hasEnterStyle = !!props.enterStyle
167
167
  const needsMount = Boolean((isWeb ? isClient : true) && (hasEnterStyle || props.animation))
168
168
  const states = useServerState<TamaguiComponentState>(
@@ -173,16 +173,38 @@ export function createComponent<
173
173
  const setState = states[1]
174
174
  const setStateShallow = useShallowSetState(setState, debugProp, componentName)
175
175
 
176
- const useAnimations = tamaguiConfig.animations?.useAnimations as UseAnimationHook | undefined
177
176
  // conditional but if ever true stays true
178
- const hasEverAnimated = useRef(false)
177
+ // [animated, inversed]
178
+ const stateRef = useRef(
179
+ undefined as any as {
180
+ hasAnimated?: boolean
181
+ hasThemeInversed?: boolean
182
+ hasProvidedThemeManager?: boolean
183
+ themeShouldReset?: boolean
184
+ }
185
+ )
186
+ stateRef.current ??= {}
187
+
179
188
  const isAnimated = (() => {
180
189
  const next = !!(useAnimations && props.animation)
181
- if (next && !hasEverAnimated.current) {
182
- hasEverAnimated.current = true
190
+ if (next && !stateRef.current.hasAnimated) {
191
+ stateRef.current.hasAnimated = true
183
192
  }
184
- return next || hasEverAnimated.current
193
+ return next || stateRef.current.hasAnimated
185
194
  })()
195
+
196
+ const usePresence = tamaguiConfig.animations?.usePresence
197
+ const presence = !isRSC && isAnimated ? usePresence() : null
198
+
199
+ // set enter/exit variants onto our new props object
200
+ if (isAnimated && presence) {
201
+ const presenceState = presence[2]
202
+ if (presenceState) {
203
+ if (presenceState.enterVariant) props[presenceState.enterVariant] = true
204
+ if (presenceState.exitVariant) props[presenceState.exitVariant] = true
205
+ }
206
+ }
207
+
186
208
  const isReactNative = Boolean(
187
209
  staticConfig.isReactNative || (isAnimated && tamaguiConfig.animations.isReactNative)
188
210
  )
@@ -200,14 +222,6 @@ export function createComponent<
200
222
  if (!isServer) {
201
223
  // eslint-disable-next-line no-console
202
224
  console.log(`state`, state)
203
- // eslint-disable-next-line no-console
204
- console.groupCollapsed('props')
205
- // eslint-disable-next-line no-console
206
- console.log(props)
207
- // eslint-disable-next-line no-console
208
- console.log('order', Object.keys(props))
209
- // eslint-disable-next-line no-console
210
- console.groupEnd()
211
225
  }
212
226
  }
213
227
  }
@@ -217,8 +231,17 @@ export function createComponent<
217
231
  const shouldForcePseudo = !!propsIn.forceStyle
218
232
  const noClassNames = shouldAvoidClasses || shouldForcePseudo
219
233
 
220
- const forceUpdate = useForceUpdate()
221
- const theme = useTheme(props.theme, componentName, props, forceUpdate, !noClassNames)
234
+ const theme = useTheme({
235
+ name: props.theme,
236
+ componentName,
237
+ reset: props.reset,
238
+ inverse: props.themeInverse,
239
+ // @ts-expect-error internal use only
240
+ disable: props['data-themeable'],
241
+ debug: props.debug,
242
+ })
243
+ const themeManager = getThemeManager(theme)
244
+ const themeIsNew = getThemeIsNewTheme(theme)
222
245
 
223
246
  const shouldSetMounted = needsMount && state.unmounted
224
247
  const setMounted = shouldSetMounted
@@ -258,6 +281,7 @@ export function createComponent<
258
281
 
259
282
  // time`setupStateConf`
260
283
 
284
+ const isExiting = presence?.[0] === false
261
285
  const splitStyles = useSplitStyles(
262
286
  props,
263
287
  staticConfig,
@@ -268,6 +292,7 @@ export function createComponent<
268
292
  dynamicStylesInline: noClassNames,
269
293
  hasTextAncestor,
270
294
  resolveVariablesAs: 'value',
295
+ isExiting,
271
296
  },
272
297
  null,
273
298
  languageContext || undefined,
@@ -325,61 +350,16 @@ export function createComponent<
325
350
  // reason is animations are heavy - no way around it, and must be run inline here (🙅 loading as a sub-component)
326
351
  let animationStyles: any
327
352
  if (!isRSC && isAnimated && useAnimations) {
328
- const animations = useAnimations(propsWithAnimation, {
353
+ const animations = useAnimations({
354
+ props: propsWithAnimation,
355
+ style: splitStylesStyle,
356
+ presence,
329
357
  state,
330
358
  pseudos,
331
359
  onDidAnimate: props.onDidAnimate,
332
360
  hostRef,
333
361
  staticConfig,
334
- getStyle({ isExiting, isEntering, exitVariant, enterVariant } = {}) {
335
- // TODO this function can mostly be moved entirely inside getSplitStyles
336
- // I think theres bugs in merge(), and we can remove that fn entirely then
337
- // also i think we need to merge both the exitVariant AND psuedos.exitStyle right now it chooses one
338
-
339
- // we have to merge such that transforms keys all exist
340
- const animationStyle = { ...defaultNativeStyle, ...splitStylesStyle }
341
-
342
- // allows for enter/exit variants on styled()
343
- const enterStyle = isEntering
344
- ? enterVariant && staticConfig.variants?.[enterVariant]['true']
345
- ? getSubStyle(
346
- '',
347
- staticConfig.variants?.[enterVariant]['true'],
348
- staticConfig,
349
- theme,
350
- props,
351
- state,
352
- tamaguiConfig
353
- )
354
- : null
355
- : null
356
-
357
- const exitStyle = isExiting
358
- ? exitVariant && staticConfig.variants?.[exitVariant]['true']
359
- ? getSubStyle(
360
- '',
361
- staticConfig.variants?.[exitVariant]['true'],
362
- staticConfig,
363
- theme,
364
- props,
365
- state,
366
- tamaguiConfig
367
- )
368
- : pseudos.exitStyle
369
- : null
370
-
371
- if (isEntering && enterStyle) {
372
- merge(animationStyle, enterStyle)
373
- }
374
- if (isExiting && exitStyle) {
375
- merge(animationStyle, exitStyle)
376
- }
377
-
378
- return animationStyle
379
- },
380
- //, delay
381
362
  })
382
-
383
363
  if (animations) {
384
364
  animationStyles = animations.style
385
365
  }
@@ -625,7 +605,7 @@ export function createComponent<
625
605
  const classList = [
626
606
  componentName ? componentClassName : '',
627
607
  fontFamilyClassName,
628
- theme.className,
608
+ themeIsNew ? theme.className : '',
629
609
  classNames ? Object.values(classNames).join(' ') : '',
630
610
  ]
631
611
  const className = classList.join(' ')
@@ -805,20 +785,22 @@ export function createComponent<
805
785
  // find space by media query
806
786
  if (state.mediaState && mediaKeys.length) {
807
787
  for (const key in state.mediaState) {
808
- if (state.mediaState[key] && props[key] && props[key].space !== undefined) {
788
+ if (key in state.mediaState && key in props && props[key].space !== undefined) {
809
789
  space = props[key].space
810
790
  }
811
791
  }
812
792
  }
813
793
 
814
- const themeManager = getThemeManager(theme)
794
+ const themeShouldReset = Boolean(themeShallow && themeManager && themeIsNew)
795
+ const shouldProvideThemeManager = themeShouldReset || (themeManager && themeIsNew)
815
796
 
816
- const shouldSetChildrenThemeToParent = Boolean(
817
- themeShallow && themeManager && themeManager.didChangeTheme
818
- )
819
-
820
- const shouldProvideThemeManager =
821
- shouldSetChildrenThemeToParent || (themeManager && themeManager.didChangeTheme)
797
+ // memoize to avoid re-parenting
798
+ if (shouldProvideThemeManager) {
799
+ stateRef.current.hasProvidedThemeManager = true
800
+ }
801
+ if (themeShouldReset) {
802
+ stateRef.current.themeShouldReset = true
803
+ }
822
804
 
823
805
  const childEls =
824
806
  !children || asChild
@@ -832,8 +814,8 @@ export function createComponent<
832
814
  isZStack,
833
815
  }),
834
816
  // only set context if changed theme
835
- shouldProvideThemeManager ? themeManager : undefined,
836
- shouldSetChildrenThemeToParent
817
+ stateRef.current.hasProvidedThemeManager ? themeManager : undefined,
818
+ stateRef.current.themeShouldReset
837
819
  )
838
820
 
839
821
  let content: any
@@ -1272,21 +1254,6 @@ function mergeConfigDefaultProps(
1272
1254
  return props
1273
1255
  }
1274
1256
 
1275
- // TODO need to delete existing prop because of weirdness in how we do this
1276
- // real solution is to handle all this in getSplitStyle and have animation drviers
1277
- // return a useAnimationIsExiting() so we can pass that as part of state: { exiting: true }
1278
- // then we can remove this function and the getStyle() altogether
1279
- function merge(base: ViewStyle, next: ViewStyle) {
1280
- for (const key in next) {
1281
- const val = next[key]
1282
- if (key in stylePropsTransform) {
1283
- mergeTransform(base, key, val, true)
1284
- } else {
1285
- base[key] = val
1286
- }
1287
- }
1288
- }
1289
-
1290
1257
  // react native compat (web only)
1291
1258
  function usePlatformMethods(hostRef: RefObject<Element>) {
1292
1259
  useIsomorphicLayoutEffect(() => {
@@ -1328,3 +1295,45 @@ const dontComposePressabilityKeys = {
1328
1295
  function getMediaStateObject(obj: Object) {
1329
1296
  return Object.fromEntries(Object.entries(obj).flatMap(([k, v]) => (v ? [[`$${k}`, v]] : [])))
1330
1297
  }
1298
+
1299
+ // function ensureBaseHasDefaults(
1300
+ // base: ViewStyle,
1301
+ // pseudos: Record<string, ViewStyle | null | undefined>
1302
+ // ) {
1303
+ // const mergeIfNotExists = (key: string) => {
1304
+ // if (!base.transform?.some((x) => key in x)) {
1305
+ // mergeTransform(base, key, transformDefaults[key] || 0)
1306
+ // }
1307
+ // }
1308
+
1309
+ // for (const name in pseudos) {
1310
+ // const pseudo = pseudos[name]
1311
+ // for (const key in pseudo) {
1312
+ // const val = pseudo[key]
1313
+ // if (key in stylePropsTransform) {
1314
+ // mergeIfNotExists(key)
1315
+ // } else if (key === 'transform') {
1316
+ // if (typeof val === 'string') continue
1317
+ // for (const t of val) {
1318
+ // mergeIfNotExists(Object.keys(t)[0])
1319
+ // }
1320
+ // } else {
1321
+ // if (key in baseDefaults && !(key in base)) {
1322
+ // base[key] = baseDefaults[key]
1323
+ // }
1324
+ // }
1325
+ // }
1326
+ // }
1327
+ // }
1328
+
1329
+ const baseDefaults = {
1330
+ opacity: 1,
1331
+ }
1332
+
1333
+ const transformDefaults = {
1334
+ opacity: 1,
1335
+ scale: 1,
1336
+ rotate: '0deg',
1337
+ rotateY: '0deg',
1338
+ rotateX: '0deg',
1339
+ }
@@ -1,4 +1,4 @@
1
- import { isRSC, isWeb } from '@tamagui/constants'
1
+ import { isClient, isRSC, isWeb } from '@tamagui/constants'
2
2
 
3
3
  import { configListeners, setConfig } from './config'
4
4
  import { createVariables } from './createVariables'
@@ -53,7 +53,7 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
53
53
 
54
54
  const themeConfig = (() => {
55
55
  const themes = { ...configIn.themes }
56
- let cssRuleSets: string[] = []
56
+ const cssRuleSets: string[] = []
57
57
 
58
58
  if (isWeb) {
59
59
  const declarations: string[] = []
@@ -140,10 +140,12 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
140
140
  }
141
141
 
142
142
  // then, generate CSS from de-duped
143
+ let themeRuleSets: string[] = []
144
+
143
145
  if (isWeb || isRSC) {
144
146
  for (const themeName in dedupedThemes) {
145
- cssRuleSets = [
146
- ...cssRuleSets,
147
+ themeRuleSets = [
148
+ ...themeRuleSets,
147
149
  ...getThemeCSSRules({
148
150
  config: configIn,
149
151
  themeName,
@@ -159,14 +161,11 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
159
161
  }
160
162
 
161
163
  tokensValueToVariable.clear()
162
- Object.freeze(cssRuleSets)
163
- const css = cssRuleSets.join('\n')
164
164
 
165
165
  return {
166
- // could improve types but we do ensureThemeVariable so its accurate
167
166
  themes,
168
167
  cssRuleSets,
169
- css,
168
+ themeRuleSets,
170
169
  }
171
170
  })()
172
171
 
@@ -179,6 +178,7 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
179
178
  )
180
179
 
181
180
  const shorthands = configIn.shorthands || {}
181
+
182
182
  const config: TamaguiInternalConfig = {
183
183
  fontLanguages: [],
184
184
  animations: {} as any,
@@ -194,12 +194,14 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
194
194
  themeConfig,
195
195
  tokensParsed,
196
196
  parsed: true,
197
- getCSS: () => `
198
- .is_Text .is_Text {display:inline-flex;}
199
- ._dsp_contents {display:contents;}
200
- ${themeConfig.css}
201
- ${getAllRules().join('\n')}
202
- `,
197
+ getCSS: (separator = '\n') => {
198
+ return `
199
+ .is_Text .is_Text {display:inline-flex;}
200
+ ._dsp_contents {display:contents;}
201
+ ${themeConfig.cssRuleSets.join(separator)}
202
+ ${themeConfig.themeRuleSets.join(separator)}
203
+ ${getAllRules().join(separator)}`
204
+ },
203
205
  // const tokens = [...getToken(tokens.size[0])]
204
206
  // .spacer-sm + ._dsp_contents._dsp-sm-hidden { margin-left: -var(--${}) }
205
207
  }
@@ -0,0 +1,29 @@
1
+ import { getDefaultTamaguiConfig } from '@tamagui/config-default-node'
2
+ import { expect, test } from 'vitest'
3
+
4
+ import { createTokens } from './createTokens'
5
+
6
+ test('snapshot', () => {
7
+ expect(createTokens(getDefaultTamaguiConfig().tokens)).toMatchSnapshot()
8
+ })
9
+
10
+ test('color name no dot', () => {
11
+ expect(
12
+ // @ts-ignore partial
13
+ createTokens({
14
+ color: {
15
+ 'yellow.10': 'yellow',
16
+ },
17
+ })
18
+ ).toMatchObject({
19
+ color: {
20
+ 'yellow.10': {
21
+ isVar: true,
22
+ key: 'yellow101a',
23
+ name: 'color-1',
24
+ val: 'yellow',
25
+ variable: '',
26
+ },
27
+ },
28
+ })
29
+ })
@@ -4,7 +4,7 @@ import { CreateTokens } from './types'
4
4
 
5
5
  // tokens.color.dark.red ===> { var: `color-dark-red`, val: '' }
6
6
  export function createTokens<T extends CreateTokens>(tokens: T): MakeTokens<T> {
7
- return createVariables(tokens as any) as any
7
+ return createVariables(tokens) as any
8
8
  }
9
9
 
10
10
  // verbose but gives us nice types...
@@ -0,0 +1,7 @@
1
+ import { expect, test } from 'vitest'
2
+
3
+ import { createCSSVariable } from './createVariable'
4
+
5
+ test('dots', () => {
6
+ expect(createCSSVariable('yellow.10')).toBe('var(--yellow101a)')
7
+ })
@@ -8,7 +8,7 @@ import { getConfig } from './config'
8
8
  * Moving to objects for React Server Components support
9
9
  */
10
10
 
11
- const IS_VAR = '__isVar__'
11
+ const IS_VAR = 'isVar'
12
12
 
13
13
  type VariableIn<A = any> = {
14
14
  val: A
@@ -23,25 +23,19 @@ export type Variable<A = any> = VariableIn<A> & {
23
23
  }
24
24
 
25
25
  export const createVariable = <A extends string | number = any>(props: VariableIn<A>) => {
26
- if (isVariable(props)) {
27
- return props
28
- }
26
+ if (isVariable(props)) return props
29
27
  return {
30
28
  [IS_VAR]: true,
31
- // @ts-ignore
32
29
  ...props,
33
30
  variable: isWeb ? createCSSVariable(props.name) : '',
34
31
  }
35
32
  }
36
33
 
37
- // on the client maybe we can change the prototype of variable object toString to keep backwards compat
38
34
  export function variableToString(vrble?: any, getValue = false) {
39
- if (!vrble) return ''
40
35
  if (isVariable(vrble)) {
41
- if (getValue) return `${vrble.val}`
42
- return `${isWeb ? vrble.variable : vrble.val}`
36
+ return getValue ? `${vrble.val}` : `${isWeb ? vrble.variable : vrble.val}`
43
37
  }
44
- return `${vrble}`
38
+ return `${vrble || ''}`
45
39
  }
46
40
 
47
41
  export function isVariable(v: Variable | any): v is Variable {
@@ -1,3 +1,5 @@
1
+ import { simpleHash } from '@tamagui/helpers'
2
+
1
3
  import { Variable, createVariable, isVariable } from './createVariable'
2
4
 
3
5
  type DeepTokenObject<Val extends string | number = any> = {
@@ -21,22 +23,20 @@ export const createVariables = <A extends DeepTokenObject>(
21
23
  let i = 0
22
24
  for (const key in tokens) {
23
25
  i++
24
- const variableName = isFont ? key.slice(0, 2) : i
25
26
  const val = tokens[key]
26
27
  if (isVariable(val)) {
27
28
  res[key] = val
28
29
  continue
29
30
  }
30
- let name = parentPath ? `${parentPath}-${variableName}` : key
31
- if (isFont && name.includes('_')) {
32
- name = name.replace(/_[a-z0-9]+/i, '')
33
- }
31
+ const niceKey = simpleHash(key)
32
+ let name = isFont ? niceKey.slice(0, 2) : i
33
+ name = parentPath ? `${parentPath}-${name}` : niceKey
34
34
  if (val && typeof val === 'object') {
35
35
  // recurse
36
- res[key] = createVariables(tokens[key] as any, `${name}`)
36
+ res[key] = createVariables(tokens[key] as any, name)
37
37
  continue
38
38
  }
39
- res[key] = isVariable(val) ? val : createVariable({ val, name, key })
39
+ res[key] = isVariable(val) ? val : createVariable({ val, name, key: niceKey })
40
40
  }
41
41
  return res
42
42
  }