@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
@@ -1,5 +1,11 @@
1
1
  import { isClient, isRSC, isServer, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
2
- import { stylePropsText, stylePropsTransform, validPseudoKeys, validStyles } from '@tamagui/helpers'
2
+ import {
3
+ stylePropsText,
4
+ stylePropsTransform,
5
+ validPseudoKeys,
6
+ validStyles,
7
+ validStylesOnBaseProps,
8
+ } from '@tamagui/helpers'
3
9
  import type { ViewStyle } from '@tamagui/types-react-native'
4
10
  import { useInsertionEffect } from 'react'
5
11
 
@@ -35,7 +41,7 @@ import {
35
41
  updateInserted,
36
42
  updateRules,
37
43
  } from './insertStyleRule'
38
- import { mergeTransform } from './mergeTransform'
44
+ import { FlatTransforms, mergeTransform, mergeTransforms } from './mergeTransform'
39
45
  import {
40
46
  normalizeValueWithProperty,
41
47
  reverseMapClassNameToValue,
@@ -55,7 +61,6 @@ const skipProps = {
55
61
  tag: true,
56
62
  }
57
63
 
58
- const emptyObject = {}
59
64
  const IS_STATIC = process.env.IS_STATIC === 'is_static'
60
65
 
61
66
  // native only skips
@@ -197,22 +202,69 @@ export const getSplitStyles: StyleSplitter = (
197
202
  staticConfig.acceptsClassName && (isWeb || IS_STATIC) && !state.noClassNames
198
203
 
199
204
  let style: ViewStyle = {}
200
- let flatTransforms: Record<string, any> | undefined
205
+ let flatTransforms: FlatTransforms | undefined
201
206
 
202
207
  const len = propKeys.length
203
208
  const rulesToInsert: RulesToInsert = []
204
209
  const classNames: ClassNamesObject = {}
210
+ let className = '' // existing classNames
205
211
  // we need to gather these specific to each media query / pseudo
206
212
  // value is [hash, val], so ["-jnjad-asdnjk", "scaleX(1) rotate(10deg)"]
207
213
  const transforms: Record<TransformNamespaceKey, [string, string]> = {}
208
214
  // fontFamily is our special baby, ensure we grab the latest set one always
209
215
  let fontFamily: string | undefined
210
216
 
217
+ if (props.className) {
218
+ for (const cn of props.className.split(' ')) {
219
+ if (cn[0] === '_') {
220
+ // tamagui, merge it expanded on key, eventually this will go away with better compiler
221
+ const [shorthand, mediaOrPseudo] = cn.slice(1).split('-')
222
+ const isMedia = mediaOrPseudo[0] === '_'
223
+ const isPseudo = mediaOrPseudo[0] === '0'
224
+ const isMediaOrPseudo = isMedia || isPseudo
225
+ let fullKey = conf.shorthands[shorthand]
226
+ if (isMedia) {
227
+ // is media
228
+ let mediaShortKey = mediaOrPseudo.slice(1)
229
+ mediaShortKey = mediaShortKey.slice(0, mediaShortKey.indexOf('_'))
230
+ fullKey += `${PROP_SPLIT}${mediaShortKey}`
231
+ } else if (isPseudo) {
232
+ // is pseudo
233
+ const pseudoShortKey = mediaOrPseudo.slice(1)
234
+ fullKey += `${PROP_SPLIT}${pseudoShortKey}`
235
+ }
236
+ if (process.env.NODE_ENV === 'development') {
237
+ if (debug) {
238
+ // eslint-disable-next-line no-console
239
+ console.log('tamagui classname', fullKey, cn)
240
+ }
241
+ }
242
+ usedKeys[fullKey] = 1
243
+ mergeClassName(transforms, classNames, fullKey, cn, isMediaOrPseudo)
244
+ } else {
245
+ if (cn) {
246
+ className += ' ' + cn
247
+ }
248
+ }
249
+ }
250
+ }
251
+
211
252
  // loop backwards so we can skip already-used props
212
253
  for (let i = len - 1; i >= 0; i--) {
213
254
  let keyInit = propKeys[i]
255
+ if (keyInit === 'className') continue // handled above
214
256
  const valInit = props[keyInit]
215
257
 
258
+ // normalize shorthands up front
259
+ const expandedKey = conf.shorthands[keyInit]
260
+ if (expandedKey) {
261
+ keyInit = expandedKey
262
+ }
263
+
264
+ if (usedKeys[keyInit]) continue
265
+ if (skipProps[keyInit]) continue
266
+ if (!isWeb && keyInit.startsWith('data-')) continue
267
+
216
268
  if (validStyleProps[keyInit] || keyInit.includes('-')) {
217
269
  if (valInit && valInit[0] === '_') {
218
270
  if (shouldDoClasses) {
@@ -225,16 +277,6 @@ export const getSplitStyles: StyleSplitter = (
225
277
  }
226
278
  }
227
279
 
228
- // normalize shorthands up front
229
- const expandedKey = conf.shorthands[keyInit]
230
- if (expandedKey) {
231
- keyInit = expandedKey
232
- }
233
-
234
- if (usedKeys[keyInit]) continue
235
- if (skipProps[keyInit]) continue
236
- if (!isWeb && keyInit.startsWith('data-')) continue
237
-
238
280
  if (keyInit === 'style' || keyInit.startsWith('_style')) {
239
281
  if (!valInit) continue
240
282
  const styles = Array.isArray(valInit) ? valInit : [valInit]
@@ -259,7 +301,12 @@ export const getSplitStyles: StyleSplitter = (
259
301
  flatTransforms ||= {}
260
302
  flatTransforms[key] = val
261
303
  } else {
262
- style[key] = normalizeValueWithProperty(val, key)
304
+ const out = normalizeValueWithProperty(val, key)
305
+ if (key in validStylesOnBaseProps) {
306
+ viewProps[key] = out
307
+ } else {
308
+ style[key] = out
309
+ }
263
310
  }
264
311
  }
265
312
 
@@ -386,40 +433,6 @@ export const getSplitStyles: StyleSplitter = (
386
433
  continue
387
434
  }
388
435
 
389
- if (keyInit === 'className') {
390
- let nonTamaguis = ''
391
- if (!valInit) continue
392
- for (const cn of valInit.split(' ')) {
393
- if (cn[0] === '_') {
394
- // tamagui, merge it expanded on key, eventually this will go away with better compiler
395
- const [shorthand, mediaOrPseudo] = cn.slice(1).split('-')
396
- const isMedia = mediaOrPseudo[0] === '_'
397
- const isPseudo = mediaOrPseudo[0] === '0'
398
- const isMediaOrPseudo = isMedia || isPseudo
399
- let fullKey = conf.shorthands[shorthand]
400
- if (isMedia) {
401
- // is media
402
- let mediaShortKey = mediaOrPseudo.slice(1)
403
- mediaShortKey = mediaShortKey.slice(0, mediaShortKey.indexOf('_'))
404
- fullKey += `${PROP_SPLIT}${mediaShortKey}`
405
- } else if (isPseudo) {
406
- // is pseudo
407
- const pseudoShortKey = mediaOrPseudo.slice(1)
408
- fullKey += `${PROP_SPLIT}${pseudoShortKey}`
409
- }
410
- usedKeys[fullKey] = 1
411
- mergeClassName(transforms, classNames, fullKey, cn, isMediaOrPseudo)
412
- } else {
413
- nonTamaguis += ' ' + cn
414
- }
415
- }
416
- if (nonTamaguis) {
417
- usedKeys[keyInit] = 1
418
- mergeClassName(transforms, classNames, keyInit, nonTamaguis)
419
- }
420
- continue
421
- }
422
-
423
436
  if (valInit && valInit[0] === '_') {
424
437
  // if valid style key (or pseudo like color-hover):
425
438
  // this conditional and esp the pseudo check rarely runs so not a perf issue
@@ -431,6 +444,12 @@ export const getSplitStyles: StyleSplitter = (
431
444
 
432
445
  if (isValidClassName || isMediaOrPseudo) {
433
446
  usedKeys[keyInit] = 1
447
+ if (process.env.NODE_ENV === 'development') {
448
+ if (debug) {
449
+ // eslint-disable-next-line no-console
450
+ console.log('tamagui classname props', keyInit, valInit)
451
+ }
452
+ }
434
453
  mergeClassName(transforms, classNames, keyInit, valInit, isMediaOrPseudo)
435
454
  continue
436
455
  }
@@ -537,22 +556,22 @@ export const getSplitStyles: StyleSplitter = (
537
556
  conf,
538
557
  languageContext,
539
558
  true,
540
- state.noClassNames
559
+ true
541
560
  )
542
561
 
543
562
  const descriptor = pseudoDescriptors[key as keyof typeof pseudoDescriptors]
544
- if (!descriptor) {
563
+ const isEnter = descriptor.name === 'enter'
564
+ const isExit = descriptor.name === 'exit'
565
+ if (!descriptor || (isEnter && !state.unmounted) || (isExit && !state.isExiting)) {
545
566
  continue
546
567
  }
547
568
 
548
- if (key !== 'enterStyle') {
549
- if (!shouldDoClasses || IS_STATIC) {
550
- pseudos[key] ||= {}
551
- Object.assign(pseudos[key], pseudoStyleObject)
552
- }
569
+ if (!shouldDoClasses || IS_STATIC) {
570
+ pseudos[key] ||= {}
571
+ Object.assign(pseudos[key], pseudoStyleObject)
553
572
  }
554
573
 
555
- if (shouldDoClasses) {
574
+ if (shouldDoClasses && !isEnter && !isExit) {
556
575
  const pseudoStyles = getAtomicStyle(pseudoStyleObject, descriptor)
557
576
  for (const psuedoStyle of pseudoStyles) {
558
577
  const fullKey = `${psuedoStyle.property}${PROP_SPLIT}${descriptor.name}`
@@ -572,7 +591,6 @@ export const getSplitStyles: StyleSplitter = (
572
591
  if (!state[descriptor.stateKey || descriptor.name]) {
573
592
  continue
574
593
  }
575
-
576
594
  psuedosUsed ||= {}
577
595
  usedKeys[key] ||= 1
578
596
  const importance = descriptor.priority
@@ -611,8 +629,7 @@ export const getSplitStyles: StyleSplitter = (
611
629
  conf,
612
630
  languageContext,
613
631
  // TODO try true like pseudo
614
- false,
615
- state.noClassNames
632
+ false
616
633
  )
617
634
 
618
635
  if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
@@ -678,9 +695,7 @@ export const getSplitStyles: StyleSplitter = (
678
695
  // always do this at the very end to preserve the order strictly (animations, origin)
679
696
  // and allow proper merging of all pseudos before applying
680
697
  if (flatTransforms) {
681
- for (const key in flatTransforms) {
682
- mergeTransform(style, key, flatTransforms[key], true)
683
- }
698
+ mergeTransforms(style, flatTransforms, true)
684
699
  }
685
700
 
686
701
  // add in defaults if not set:
@@ -700,17 +715,6 @@ export const getSplitStyles: StyleSplitter = (
700
715
  style[key] = parentSplitStyles.style[key]
701
716
  }
702
717
  }
703
- if (process.env.NODE_ENV === 'development') {
704
- if (debug === 'verbose') {
705
- // eslint-disable-next-line no-console
706
- console.log(` add in parent styled()`, {
707
- parentSplitStyles,
708
- shouldDoClasses,
709
- style: { ...style },
710
- classNames: { ...classNames },
711
- })
712
- }
713
- }
714
718
  }
715
719
 
716
720
  if (process.env.TAMAGUI_TARGET === 'web') {
@@ -741,15 +745,13 @@ export const getSplitStyles: StyleSplitter = (
741
745
  }
742
746
  const [hash, val] = transforms[namespace]
743
747
  const identifier = `_transform${hash}`
744
- if (isClient) {
745
- if (!insertedTransforms[identifier]) {
746
- const rule = `.${identifier} { transform: ${val}; }`
747
- addStyleToInsertRules(rulesToInsert, {
748
- identifier,
749
- rules: [rule],
750
- property: namespace,
751
- })
752
- }
748
+ if (isClient && !insertedTransforms[identifier]) {
749
+ const rule = `.${identifier} { transform: ${val}; }`
750
+ addStyleToInsertRules(rulesToInsert, {
751
+ identifier,
752
+ rules: [rule],
753
+ property: namespace,
754
+ })
753
755
  }
754
756
  classNames[namespace] = identifier
755
757
  }
@@ -761,7 +763,8 @@ export const getSplitStyles: StyleSplitter = (
761
763
  // prettier-ignore
762
764
  // eslint-disable-next-line no-console
763
765
  console.groupCollapsed(' 🔹 styles =>')
764
- const logs = { style, pseudos, medias, classNames, viewProps, state, rulesToInsert }
766
+ // prettier-ignore
767
+ const logs = { style, pseudos, medias, classNames, transforms,viewProps, state, rulesToInsert, parentSplitStyles, flatTransforms }
765
768
  for (const key in logs) {
766
769
  // eslint-disable-next-line no-console
767
770
  console.log(key, logs[key])
@@ -771,6 +774,10 @@ export const getSplitStyles: StyleSplitter = (
771
774
  }
772
775
  }
773
776
 
777
+ if (className) {
778
+ classNames.className = className
779
+ }
780
+
774
781
  return {
775
782
  fontFamily,
776
783
  viewProps,
@@ -845,16 +852,14 @@ const cache = new WeakMap()
845
852
  function getSubStyleProps(defaultProps: Object, baseProps: Object, specificProps: Object) {
846
853
  const key = specificProps || baseProps
847
854
  // can cache based only on specific it's always referentially consistent with base
848
- if (cache.has(key)) {
849
- return cache.get(key)
850
- }
851
- const next = {
852
- ...defaultProps,
853
- ...baseProps,
854
- ...specificProps,
855
+ if (!cache.has(key)) {
856
+ cache.set(key, {
857
+ ...defaultProps,
858
+ ...baseProps,
859
+ ...specificProps,
860
+ })
855
861
  }
856
- cache.set(key, next)
857
- return next
862
+ return cache.get(key)!
858
863
  }
859
864
 
860
865
  export const getSubStyle = (
@@ -86,8 +86,15 @@ export function getThemeCSSRules({
86
86
  }
87
87
  }
88
88
 
89
- const rootSep = config.themeClassNameOnRoot ? '' : ' '
90
- const css = `${selectors.map((x) => `:root${rootSep}${x}`).join(', ')} {${vars}}`
89
+ const selectorsString = selectors.map((x) => {
90
+ // only do our :root attach if it's not light/dark - not support sub themes on root saves a lot of effort/size
91
+ // this isBaseTheme logic could probably be done more efficiently above
92
+ const isBaseTheme =
93
+ x === '.t_dark' || x === '.t_light' || x.startsWith('.t_dark ') || x.startsWith('.t_light ')
94
+ const rootSep = isBaseTheme && config.themeClassNameOnRoot ? '' : ' '
95
+ return `:root${rootSep}${x}`
96
+ })
97
+ const css = `${selectorsString.join(', ')} {${vars}}`
91
98
  cssRuleSets.push(css)
92
99
 
93
100
  if (config.shouldAddPrefersColorThemes && isDarkOrLightBase) {
@@ -5,7 +5,7 @@
5
5
  import type { StyleObject } from '@tamagui/helpers'
6
6
 
7
7
  const allSelectors: Record<string, string> = {}
8
- const allRules: Record<string, boolean | string[]> = {}
8
+ const allRules: Record<string, string> = {}
9
9
  export const insertedTransforms = {}
10
10
 
11
11
  export const getAllSelectors = () => allSelectors
@@ -122,7 +122,7 @@ const sheet = isClient ? document.head.appendChild(document.createElement('style
122
122
 
123
123
  export function updateRules(identifier: string, rules: string[]) {
124
124
  if (allRules[identifier]) return false
125
- allRules[identifier] = rules
125
+ allRules[identifier] = rules.join(' ')
126
126
  if (identifier.startsWith('_transform')) {
127
127
  return addTransform(identifier, rules[0])
128
128
  }
@@ -1,16 +1,23 @@
1
1
  import type { ViewStyle } from '@tamagui/types-react-native'
2
2
 
3
+ export type FlatTransforms = Record<string, any>
4
+
3
5
  export const mergeTransform = (obj: ViewStyle, key: string, val: any, backwards = false) => {
4
6
  obj.transform ||= []
5
7
  obj.transform[backwards ? 'unshift' : 'push']({ [mapTransformKeys[key] || key]: val } as any)
6
8
  }
7
9
 
8
- const mapTransformKeys = {
9
- x: 'translateX',
10
- y: 'translateY',
10
+ export const mergeTransforms = (
11
+ obj: ViewStyle,
12
+ flatTransforms: FlatTransforms,
13
+ backwards = false
14
+ ) => {
15
+ Object.entries(flatTransforms).forEach(([key, val]) => {
16
+ mergeTransform(obj, key, val, backwards)
17
+ })
11
18
  }
12
19
 
13
- export const invertMapTransformKeys = {
14
- translateX: 'x',
15
- translateY: 'y',
20
+ export const mapTransformKeys = {
21
+ x: 'translateX',
22
+ y: 'translateY',
16
23
  }
@@ -24,6 +24,7 @@ export const pseudoDescriptors: Record<
24
24
  },
25
25
  exitStyle: {
26
26
  name: 'exit',
27
+ stateKey: 'isExiting',
27
28
  priority: 5,
28
29
  },
29
30
  }
@@ -1,27 +1,35 @@
1
- import React, { forwardRef } from 'react'
1
+ import React, { forwardRef, useId } from 'react'
2
2
 
3
3
  import { ThemeName } from '../types'
4
4
  import { Theme } from '../views/Theme'
5
- import { ThemeInverse } from '../views/ThemeInverse'
6
5
 
7
6
  export interface ThemeableProps {
8
7
  theme?: ThemeName | null
9
8
  themeInverse?: boolean
9
+ componentName?: string
10
+ debug?: boolean | 'verbose'
11
+ reset?: boolean
10
12
  }
11
13
 
12
14
  export function themeable<Component extends (props: any) => any>(
13
15
  component: Component,
14
16
  opts?: { componentName?: string }
15
17
  ) {
16
- const withThemeComponent = forwardRef(function WithTheme(props: any, ref) {
17
- const { themeInverse, theme, ...rest } = props
18
+ const withThemeComponent = forwardRef(function WithTheme(props: ThemeableProps, ref) {
19
+ const { themeInverse, theme, componentName, reset, ...rest } = props
18
20
  const element = React.createElement(component, { ...rest, ref } as any)
21
+
19
22
  return (
20
- <ThemeInverse disable={!themeInverse}>
21
- <Theme componentName={opts?.componentName} name={(theme as any) || null}>
22
- {element}
23
- </Theme>
24
- </ThemeInverse>
23
+ <Theme
24
+ inverse={themeInverse}
25
+ componentName={componentName || opts?.componentName}
26
+ name={(theme as any) || null}
27
+ data-themeable
28
+ debug={props.debug}
29
+ reset={props.reset}
30
+ >
31
+ {element}
32
+ </Theme>
25
33
  )
26
34
  })
27
35
 
@@ -1,8 +1,10 @@
1
1
  import { useIsomorphicLayoutEffect } from '@tamagui/constants'
2
- import { getBoundingClientRect } from '@tamagui/react-native-use-responder-events'
3
2
  import { useEvent } from '@tamagui/use-event'
4
3
  import { RefObject } from 'react'
5
4
 
5
+ import { getBoundingClientRect } from '../helpers/getBoundingClientRect'
6
+ import { getRect } from '../helpers/getRect'
7
+
6
8
  const LayoutHandlers = new WeakMap<Element, Function>()
7
9
 
8
10
  export type LayoutValue = {
@@ -42,13 +44,6 @@ if (typeof window !== 'undefined' && 'ResizeObserver' in window) {
42
44
  })
43
45
  }
44
46
 
45
- export const getRect = (node: HTMLElement) => {
46
- const rect = getBoundingClientRect(node)
47
- if (!rect) return
48
- const { x, y, top, left } = rect
49
- return { x, y, width: node.offsetWidth, height: node.offsetHeight, top, left }
50
- }
51
-
52
47
  export const measureLayout = (
53
48
  node: HTMLElement,
54
49
  relativeTo: HTMLElement | null,
@@ -1,4 +1,4 @@
1
- import { useEffect, useMemo, useSyncExternalStore } from 'react'
1
+ import { useDeferredValue, useEffect, useMemo, useSyncExternalStore } from 'react'
2
2
 
3
3
  import { getConfig } from '../config'
4
4
  import { createProxy } from '../helpers/createProxy'
@@ -156,8 +156,7 @@ export function useMedia(): {
156
156
  [key in MediaQueryKey]: boolean
157
157
  } {
158
158
  const keys = useSafeRef<MediaKeysState>({ prev: initState })
159
-
160
- const state = useSyncExternalStore<MediaQueryState>(
159
+ const stateSync = useSyncExternalStore<MediaQueryState>(
161
160
  subscribe,
162
161
  () => {
163
162
  const { prev, ...curKeys } = keys.current
@@ -171,6 +170,7 @@ export function useMedia(): {
171
170
  },
172
171
  () => initState
173
172
  )
173
+ const state = useDeferredValue(stateSync)
174
174
 
175
175
  return useMemo(() => {
176
176
  return new Proxy(state, {