@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/types.tsx CHANGED
@@ -264,6 +264,17 @@ export type AnimationKeys = TamaguiConfig['animations'] extends AnimationDriver<
264
264
  : string
265
265
  export type FontLanguages = ArrayIntersection<TamaguiConfig['fontLanguages']>
266
266
 
267
+ export interface ThemeProps {
268
+ className?: string
269
+ disableThemeClass?: boolean
270
+ name?: Exclude<ThemeName, number> | null
271
+ componentName?: string
272
+ children?: any
273
+ reset?: boolean
274
+ debug?: boolean | 'verbose'
275
+ inverse?: boolean
276
+ }
277
+
267
278
  type ArrayIntersection<A extends any[]> = A[keyof A]
268
279
 
269
280
  type GetAltThemeNames<S> = (S extends `${string}_${infer Alt}` ? GetAltThemeNames<Alt> : S) | S
@@ -1242,8 +1253,33 @@ export type SplitStyleState = TamaguiComponentState & {
1242
1253
  fallbackProps?: Record<string, any>
1243
1254
  keepVariantsAsProps?: boolean
1244
1255
  hasTextAncestor?: boolean
1256
+
1257
+ // for animations
1258
+ isExiting?: boolean
1259
+ exitVariant?: string
1260
+ enterVariant?: string
1245
1261
  }
1246
1262
 
1263
+ // Presence
1264
+
1265
+ export interface PresenceContextProps {
1266
+ id: string
1267
+ isPresent: boolean
1268
+ register: (id: string) => () => void
1269
+ onExitComplete?: (id: string) => void
1270
+ initial?: false | string | string[]
1271
+ custom?: any
1272
+ exitVariant?: string | null
1273
+ enterVariant?: string | null
1274
+ }
1275
+
1276
+ type SafeToRemoveCallback = () => void
1277
+ type AlwaysPresent = [true, null, null]
1278
+ type Present = [true, undefined, PresenceContextProps]
1279
+ type NotPresent = [false, SafeToRemoveCallback, PresenceContextProps]
1280
+
1281
+ export type UsePresenceResult = AlwaysPresent | Present | NotPresent
1282
+
1247
1283
  // Animations:
1248
1284
 
1249
1285
  type AnimationConfig = {
@@ -1277,6 +1313,7 @@ export type UniversalAnimatedNumber<A> = {
1277
1313
  export type AnimationDriver<A extends AnimationConfig = AnimationConfig> = {
1278
1314
  isReactNative?: boolean
1279
1315
  useAnimations: UseAnimationHook
1316
+ usePresence: () => UsePresenceResult
1280
1317
  useAnimatedNumber: (initial: number) => UniversalAnimatedNumber<any>
1281
1318
  useAnimatedNumberStyle: <V extends UniversalAnimatedNumber<any>>(
1282
1319
  val: V,
@@ -1293,29 +1330,17 @@ export type AnimationDriver<A extends AnimationConfig = AnimationConfig> = {
1293
1330
 
1294
1331
  export type UseAnimationProps = TamaguiComponentPropsBase & Record<string, any>
1295
1332
 
1296
- export type UseAnimationHelpers = {
1333
+ export type UseAnimationHook = (props: {
1334
+ style: Record<string, any>
1335
+ props: Record<string, any>
1336
+ presence?: UsePresenceResult | null
1297
1337
  hostRef: RefObject<HTMLElement | View>
1298
1338
  staticConfig: StaticConfigParsed
1299
- getStyle: (props?: {
1300
- isEntering?: boolean
1301
- isExiting?: boolean
1302
- exitVariant?: string | null
1303
- enterVariant?: string | null
1304
- }) => ViewStyle
1305
1339
  state: SplitStyleState
1306
1340
  pseudos: PseudoProps<ViewStyle>
1307
- // style: ViewStyle | null | undefined
1308
- // isMounted: boolean
1309
- // exitStyle?: ViewStyle | null
1310
1341
  onDidAnimate?: any
1311
1342
  delay?: number
1312
- // mergedStyles(props?: { isExiting?: boolean }): ViewStyle
1313
- }
1314
-
1315
- export type UseAnimationHook = (
1316
- props: UseAnimationProps,
1317
- helpers: UseAnimationHelpers
1318
- ) => null | {
1343
+ }) => null | {
1319
1344
  style?: StackStylePropsBase | StackStylePropsBase[]
1320
1345
  }
1321
1346
 
@@ -2,19 +2,22 @@ import { addTheme } from './addTheme'
2
2
  import { activeThemeManagers } from './hooks/useTheme'
3
3
  import { ThemeDefinition } from './types'
4
4
 
5
- export function updateTheme({ name, theme }: { name: string; theme: ThemeDefinition }) {
5
+ export function updateTheme({
6
+ name,
7
+ theme,
8
+ }: {
9
+ name: string
10
+ theme: Partial<Record<keyof ThemeDefinition, any>>
11
+ }) {
6
12
  const next = addTheme({ name, theme, insertCSS: true, update: true })
7
13
 
8
14
  if (process.env.TAMAGUI_TARGET === 'native') {
9
15
  activeThemeManagers.forEach((manager) => {
10
- if (manager.name === name) {
11
- manager.update(
12
- {
13
- name,
14
- theme: next.theme,
15
- },
16
- true
17
- )
16
+ if (manager.state.name === name) {
17
+ manager.updateState({
18
+ name,
19
+ forceTheme: next.theme,
20
+ })
18
21
  }
19
22
  })
20
23
  }
@@ -1,7 +1,7 @@
1
- import { isClient, isRSC, isServer } from '@tamagui/constants'
1
+ import { isClient, isRSC, isServer, isWeb } from '@tamagui/constants'
2
2
  import * as React from 'react'
3
3
 
4
- import { ButtonInsideButtonContext } from '../contexts/ButtonInsideButtonContext'
4
+ import { ButtonNestingContext } from '../contexts/ButtonNestingContext'
5
5
  import { TextAncestorContext } from '../contexts/TextAncestorContext'
6
6
  import { useMediaListeners } from '../hooks/useMedia'
7
7
  import type { TamaguiProviderProps } from '../types'
@@ -24,7 +24,7 @@ export function TamaguiProvider({
24
24
  )
25
25
  }
26
26
 
27
- if (!isServer) {
27
+ if (!isWeb || !isServer) {
28
28
  useMediaListeners(config)
29
29
  }
30
30
 
@@ -43,7 +43,7 @@ export function TamaguiProvider({
43
43
  }
44
44
 
45
45
  return (
46
- <ButtonInsideButtonContext.Provider value={false}>
46
+ <ButtonNestingContext.Provider value={false}>
47
47
  <TextAncestorContext.Provider value={false}>
48
48
  <ThemeProvider
49
49
  themeClassNameOnRoot={config.themeClassNameOnRoot}
@@ -54,6 +54,6 @@ export function TamaguiProvider({
54
54
  {children}
55
55
  </ThemeProvider>
56
56
  </TextAncestorContext.Provider>
57
- </ButtonInsideButtonContext.Provider>
57
+ </ButtonNestingContext.Provider>
58
58
  )
59
59
  }
@@ -1,48 +1,56 @@
1
1
  import { isWeb } from '@tamagui/constants'
2
- import React, { memo, useMemo } from 'react'
2
+ import React, { useMemo } from 'react'
3
3
 
4
4
  import { variableToString } from '../createVariable'
5
- import { ThemeManager, ThemeManagerContext } from '../helpers/ThemeManager'
6
- import { ThemeProps, useChangeThemeEffect } from '../hooks/useTheme'
5
+ import { ThemeManager } from '../helpers/ThemeManager'
6
+ import { ThemeManagerContext } from '../helpers/ThemeManagerContext'
7
+ import { useChangeThemeEffect } from '../hooks/useTheme'
8
+ import { ThemeProps } from '../types'
7
9
 
8
- // bugfix esbuild strips react jsx: 'preserve'
9
- React['createElement']
10
+ export function Theme(props: ThemeProps) {
11
+ // @ts-expect-error its a permanent prop meant for internal views
12
+ if (props.disable) {
13
+ return props.children
14
+ }
10
15
 
11
- export const Theme = memo(function Theme(props: ThemeProps) {
12
- const { name, theme, themeManager, themes, className } = useChangeThemeEffect(
13
- props.name,
14
- props.componentName,
15
- props
16
+ const isRoot = !!props['_isRoot']
17
+ const { name, theme, themeManager, themes, isNewTheme, className } = useChangeThemeEffect(
18
+ props,
19
+ isRoot
16
20
  )
17
21
 
22
+ const disableThemeClass = props.disableThemeClass
18
23
  const missingTheme = !themes || !name || !theme
24
+ const disablePassingTheme = missingTheme || !isNewTheme
19
25
 
20
26
  // memo here, changing theme without re-rendering all children is a critical optimization
21
27
  // may require some effort of end user to memoize but without this memo they'd have no option
22
- const contents = useMemo(
23
- () => (missingTheme ? null : wrapThemeManagerContext(props.children, themeManager)),
24
- [missingTheme, props.children, themeManager]
25
- )
28
+ let contents = useMemo(() => {
29
+ const next = props['data-themeable']
30
+ ? React.cloneElement(props.children, { ['data-themeable']: true })
31
+ : props.children
26
32
 
27
- if (missingTheme) {
28
- if (name && !theme && process.env.NODE_ENV === 'development') {
29
- // eslint-disable-next-line no-console
30
- console.warn(`No theme found by name ${name}`)
31
- }
33
+ return disablePassingTheme ? next : wrapThemeManagerContext(next, themeManager)
34
+ }, [disablePassingTheme, props.children, themeManager])
35
+
36
+ if (process.env.NODE_ENV === 'development' && missingTheme) {
37
+ // eslint-disable-next-line no-console
38
+ name && !theme && console.warn(`No theme found by name ${name}`)
32
39
  return props.children
33
40
  }
34
41
 
42
+ if (disableThemeClass || disablePassingTheme) {
43
+ return contents
44
+ }
45
+
35
46
  if (isWeb) {
36
- return (
47
+ const cn = [props.className, className, '_dsp_contents'].filter(Boolean).join(' ')
48
+ contents = (
37
49
  <span
38
- className={(!props.disableThemeClass
39
- ? [props.className, className].filter(Boolean)
40
- : []
41
- ).join(' ')}
50
+ className={cn}
42
51
  style={{
43
- display: 'contents',
44
52
  // in order to provide currentColor, set color by default
45
- color: variableToString(themes[name]?.color),
53
+ color: variableToString(theme?.color),
46
54
  }}
47
55
  >
48
56
  {contents}
@@ -51,22 +59,23 @@ export const Theme = memo(function Theme(props: ThemeProps) {
51
59
  }
52
60
 
53
61
  return contents
54
- })
62
+ }
55
63
 
56
64
  export function wrapThemeManagerContext(
57
65
  children: any,
58
66
  themeManager?: ThemeManager | null,
59
- shouldSetChildrenThemeToParent?: boolean
67
+ shouldReset?: boolean
60
68
  ) {
61
- return themeManager ? (
62
- <ThemeManagerContext.Provider value={themeManager}>
63
- {shouldSetChildrenThemeToParent ? (
64
- <Theme name={themeManager.parentName}>{children}</Theme>
65
- ) : (
66
- children
67
- )}
68
- </ThemeManagerContext.Provider>
69
- ) : (
70
- children
71
- )
69
+ // be sure to memoize themeManager to avoid reparenting
70
+ if (!themeManager) {
71
+ return children
72
+ }
73
+ // be sure to memoize shouldReset to avoid reparenting
74
+ let next = children
75
+ // TODO likely not necessary if we do reset logic now in useTheme?
76
+ // reset to parent theme
77
+ if (shouldReset && themeManager) {
78
+ next = <Theme name={themeManager.state.parentName}>{next}</Theme>
79
+ }
80
+ return <ThemeManagerContext.Provider value={themeManager}>{next}</ThemeManagerContext.Provider>
72
81
  }
@@ -1,14 +1,9 @@
1
1
  import { isClient } from '@tamagui/constants'
2
- import React, { useLayoutEffect, useMemo } from 'react'
2
+ import { useLayoutEffect } from 'react'
3
3
 
4
- import { getConfig, getHasConfigured } from '../config'
5
4
  import { THEME_CLASSNAME_PREFIX } from '../constants/constants'
6
- import { ThemeContext } from '../contexts/ThemeContext'
7
5
  import { Theme } from './Theme'
8
6
 
9
- // bugfix esbuild strips react jsx: 'preserve'
10
- React['createElement']
11
-
12
7
  export type ThemeProviderProps = {
13
8
  className?: string
14
9
  defaultTheme: string
@@ -19,18 +14,10 @@ export type ThemeProviderProps = {
19
14
  }
20
15
 
21
16
  export const ThemeProvider = (props: ThemeProviderProps) => {
22
- if (process.env.NODE_ENV === 'development') {
23
- if (!getHasConfigured()) {
24
- throw new Error(`Missing configureThemes() call, add to your root file`)
25
- }
26
- }
27
-
28
17
  // ensure theme is attached to root body node as well to work with modals by default
29
18
  if (isClient) {
30
19
  useLayoutEffect(() => {
31
- if (props.disableRootThemeClass) {
32
- return
33
- }
20
+ if (props.disableRootThemeClass) return
34
21
  const cn = `${THEME_CLASSNAME_PREFIX}${props.defaultTheme}`
35
22
  const target = props.themeClassNameOnRoot ? document.documentElement : document.body
36
23
  target.classList.add(cn)
@@ -40,24 +27,15 @@ export const ThemeProvider = (props: ThemeProviderProps) => {
40
27
  }, [props.defaultTheme, props.disableRootThemeClass, props.themeClassNameOnRoot])
41
28
  }
42
29
 
43
- const themeContext = useMemo(() => {
44
- return {
45
- get themes() {
46
- return getConfig().themes
47
- },
48
- defaultTheme: props.defaultTheme,
49
- }
50
- }, [props.defaultTheme])
51
-
52
30
  return (
53
- <ThemeContext.Provider value={themeContext}>
54
- <Theme
55
- className={props.className}
56
- name={props.defaultTheme}
57
- disableThemeClass={props.disableRootThemeClass}
58
- >
59
- {props.children}
60
- </Theme>
61
- </ThemeContext.Provider>
31
+ <Theme
32
+ className={props.className}
33
+ name={props.defaultTheme}
34
+ disableThemeClass={props.disableRootThemeClass}
35
+ // @ts-expect-error
36
+ _isRoot
37
+ >
38
+ {props.children}
39
+ </Theme>
62
40
  )
63
41
  }
@@ -18,7 +18,7 @@ declare class TamaguiManager {
18
18
  [key: string]: any;
19
19
  };
20
20
  }, import("./types").GenericFonts>;
21
- get insertedRules(): (boolean | string[])[];
21
+ get insertedRules(): string[];
22
22
  get allSelectors(): Record<string, string>;
23
23
  get allTransforms(): {};
24
24
  get identifierToValue(): Map<string, any>;
@@ -1,10 +1,31 @@
1
1
  import { ThemeDefinition } from './types';
2
- export declare function addTheme({ name: themeName, theme: themeIn, insertCSS, update, }: {
2
+ export declare function addTheme(props: {
3
3
  name: string;
4
- theme: ThemeDefinition;
4
+ theme: Partial<Record<keyof ThemeDefinition, any>>;
5
5
  insertCSS?: boolean;
6
6
  update?: boolean;
7
7
  }): {
8
+ theme: {
9
+ [x: string]: import("./createVariable").Variable<any>;
10
+ background?: import("./createVariable").Variable<any> | undefined;
11
+ backgroundHover?: import("./createVariable").Variable<any> | undefined;
12
+ backgroundPress?: import("./createVariable").Variable<any> | undefined;
13
+ backgroundFocus?: import("./createVariable").Variable<any> | undefined;
14
+ color?: import("./createVariable").Variable<any> | undefined;
15
+ colorHover?: import("./createVariable").Variable<any> | undefined;
16
+ colorPress?: import("./createVariable").Variable<any> | undefined;
17
+ colorFocus?: import("./createVariable").Variable<any> | undefined;
18
+ borderColor?: import("./createVariable").Variable<any> | undefined;
19
+ borderColorHover?: import("./createVariable").Variable<any> | undefined;
20
+ borderColorPress?: import("./createVariable").Variable<any> | undefined;
21
+ borderColorFocus?: import("./createVariable").Variable<any> | undefined;
22
+ shadowColor?: import("./createVariable").Variable<any> | undefined;
23
+ shadowColorHover?: import("./createVariable").Variable<any> | undefined;
24
+ shadowColorPress?: import("./createVariable").Variable<any> | undefined;
25
+ shadowColorFocus?: import("./createVariable").Variable<any> | undefined;
26
+ };
27
+ cssRules?: undefined;
28
+ } | {
8
29
  theme: any;
9
30
  cssRules: string[];
10
31
  };
package/types/config.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ConfigListener, TamaguiInternalConfig, Tokens } from './types';
2
2
  export declare const setConfig: (next: TamaguiInternalConfig) => void;
3
3
  export declare const setConfigFont: (name: string, font: any, fontParsed: any) => void;
4
- export declare const getHasConfigured: () => boolean;
5
4
  export declare const getConfig: () => TamaguiInternalConfig<import("./types").CreateTokens<import("./types").VariableVal>, {
6
5
  [key: string]: Partial<import("./types").TamaguiBaseTheme> & {
7
6
  [key: string]: import("./types").VariableVal;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ export declare const ButtonNestingContext: import("react").Context<boolean>;
3
+ //# sourceMappingURL=ButtonNestingContext.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createTokens.test.d.ts.map
@@ -2,7 +2,7 @@
2
2
  * Should rename this to Token
3
3
  * Moving to objects for React Server Components support
4
4
  */
5
- declare const IS_VAR = "__isVar__";
5
+ declare const IS_VAR = "isVar";
6
6
  declare type VariableIn<A = any> = {
7
7
  val: A;
8
8
  name: string;
@@ -19,7 +19,7 @@ export declare const createVariable: <A extends string | number = any>(props: Va
19
19
  name: string;
20
20
  key: string;
21
21
  isFloating?: boolean | undefined;
22
- __isVar__: boolean;
22
+ isVar: boolean;
23
23
  };
24
24
  export declare function variableToString(vrble?: any, getValue?: boolean): string;
25
25
  export declare function isVariable(v: Variable | any): v is Variable;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createVariable.test.d.ts.map
@@ -1,45 +1,35 @@
1
- /// <reference types="react" />
2
- import { ThemeParsed, Themes } from '../types';
1
+ import { ThemeParsed, ThemeProps } from '../types';
3
2
  declare type ThemeListener = (name: string | null, themeManager: ThemeManager) => void;
4
3
  export declare type SetActiveThemeProps = {
5
4
  className?: string;
6
5
  parentManager?: ThemeManager | null;
7
6
  name?: string | null;
8
7
  theme?: any;
9
- };
10
- export declare type GetNextThemeProps = {
11
- themes?: Themes;
12
- name?: string | null;
13
- componentName?: string | null;
14
8
  reset?: boolean;
15
9
  };
16
- export declare class ThemeManager {
10
+ export declare type ThemeManagerState = {
17
11
  name: string;
18
- className: string;
19
- theme: ThemeParsed | null;
20
- parentManager: ThemeManager | null;
21
- reset: boolean;
22
- keys: Map<any, Set<string>>;
23
- listeners: Map<any, Function>;
12
+ theme?: ThemeParsed | null;
13
+ className?: string;
14
+ parentName?: string;
15
+ };
16
+ export declare function hasNoThemeUpdatingProps(props: ThemeProps): boolean;
17
+ export declare class ThemeManager {
18
+ #private;
19
+ props: ThemeProps;
24
20
  themeListeners: Set<ThemeListener>;
25
- constructor(name?: string, className?: string, theme?: ThemeParsed | null, parentManager?: ThemeManager | null, reset?: boolean);
26
- get didChangeTheme(): boolean | null;
27
- get parentName(): string | null;
28
- get fullName(): string;
29
- getValue(key: string): import("..").Variable<any> | undefined;
30
- isTracking(uuid: Object): boolean;
31
- update({ name, theme, className }?: SetActiveThemeProps, force?: boolean, notify?: boolean): boolean;
32
- getNextTheme(props?: GetNextThemeProps, debug?: any): {
33
- name: string;
34
- theme: ThemeParsed | null;
35
- className: string | undefined;
36
- };
37
- getCN(name: string): string;
38
- track(uuid: any, keys: Set<string>): void;
21
+ parentManager: ThemeManager | null;
22
+ state: ThemeManagerState;
23
+ constructor(props?: ThemeProps, parentManager?: ThemeManager | 'root' | null | undefined);
24
+ updateState(props?: ThemeProps & {
25
+ forceTheme?: ThemeParsed;
26
+ }, notify?: boolean): ThemeManagerState | undefined;
27
+ getStateIfChanged(props?: ThemeProps, state?: ThemeManagerState, parentManager?: ThemeManager | null): ThemeManagerState | null;
28
+ getState(props?: ThemeProps): ThemeManagerState | null;
29
+ get allKeys(): Set<string>;
30
+ getValue(key: string, state?: ThemeManagerState): import("..").Variable<any> | undefined;
39
31
  notify(): void;
40
32
  onChangeTheme(cb: ThemeListener): () => void;
41
33
  }
42
- export declare const ThemeManagerContext: import("react").Context<ThemeManager | null>;
43
- export declare const emptyManager: ThemeManager;
44
34
  export {};
45
35
  //# sourceMappingURL=ThemeManager.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ThemeManager.test.d.ts.map
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { ThemeManager } from './ThemeManager';
3
+ export declare const ThemeManagerContext: import("react").Context<ThemeManager | null>;
4
+ //# sourceMappingURL=ThemeManagerContext.d.ts.map
@@ -0,0 +1,2 @@
1
+ export declare const getBoundingClientRect: (node: HTMLElement | null) => void | DOMRect;
2
+ //# sourceMappingURL=getBoundingClientRect.d.ts.map
@@ -0,0 +1,9 @@
1
+ export declare const getRect: (node: HTMLElement) => {
2
+ x: number;
3
+ y: number;
4
+ width: number;
5
+ height: number;
6
+ top: number;
7
+ left: number;
8
+ } | undefined;
9
+ //# sourceMappingURL=getRect.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import type { StyleObject } from '@tamagui/helpers';
2
2
  export declare const insertedTransforms: {};
3
3
  export declare const getAllSelectors: () => Record<string, string>;
4
- export declare const getAllRules: () => (boolean | string[])[];
4
+ export declare const getAllRules: () => string[];
5
5
  export declare const getAllTransforms: () => {};
6
6
  export declare function updateInserted(): void;
7
7
  export declare function updateRules(identifier: string, rules: string[]): boolean;
@@ -1,7 +1,9 @@
1
1
  import type { ViewStyle } from '@tamagui/types-react-native';
2
+ export declare type FlatTransforms = Record<string, any>;
2
3
  export declare const mergeTransform: (obj: ViewStyle, key: string, val: any, backwards?: boolean) => void;
3
- export declare const invertMapTransformKeys: {
4
- translateX: string;
5
- translateY: string;
4
+ export declare const mergeTransforms: (obj: ViewStyle, flatTransforms: FlatTransforms, backwards?: boolean) => void;
5
+ export declare const mapTransformKeys: {
6
+ x: string;
7
+ y: string;
6
8
  };
7
9
  //# sourceMappingURL=mergeTransform.d.ts.map
@@ -2,6 +2,9 @@ import { ThemeName } from '../types';
2
2
  export interface ThemeableProps {
3
3
  theme?: ThemeName | null;
4
4
  themeInverse?: boolean;
5
+ componentName?: string;
6
+ debug?: boolean | 'verbose';
7
+ reset?: boolean;
5
8
  }
6
9
  export declare function themeable<Component extends (props: any) => any>(component: Component, opts?: {
7
10
  componentName?: string;
@@ -14,14 +14,6 @@ export declare type LayoutEvent = {
14
14
  };
15
15
  timeStamp: number;
16
16
  };
17
- export declare const getRect: (node: HTMLElement) => {
18
- x: number;
19
- y: number;
20
- width: number;
21
- height: number;
22
- top: number;
23
- left: number;
24
- } | undefined;
25
17
  export declare const measureLayout: (node: HTMLElement, relativeTo: HTMLElement | null, callback: Function) => void;
26
18
  export declare function useElementLayout(ref: RefObject<Element>, onLayout?: ((e: LayoutEvent) => void) | null): void;
27
19
  //# sourceMappingURL=useElementLayout.d.ts.map
@@ -1,26 +1,16 @@
1
1
  import { ThemeManager } from '../helpers/ThemeManager';
2
- import { ThemeName, ThemeParsed } from '../types';
3
- export interface ThemeProps {
4
- className?: string;
5
- disableThemeClass?: boolean;
6
- name: Exclude<ThemeName, number> | null;
7
- componentName?: string;
8
- children?: any;
9
- reset?: boolean;
10
- debug?: boolean | 'verbose';
11
- }
12
- export declare const useTheme: (themeName?: string | null, componentName?: string, props?: ThemeProps, forceUpdate?: any, disableTracking?: boolean) => ThemeParsed;
13
- export declare const getThemeManager: (theme: any) => ThemeManager | undefined;
14
- export declare function useThemeName(opts?: {
15
- parent?: true;
16
- }): ThemeName;
17
- export declare const useDefaultThemeName: () => string | undefined;
18
- export declare const activeThemeManagers: Set<ThemeManager>;
19
- export declare const useChangeThemeEffect: (name?: string | null, componentName?: string, props?: ThemeProps, forceUpdateProp?: any, uuid?: Object) => {
2
+ import { ThemeParsed, ThemeProps } from '../types';
3
+ export declare type ChangedThemeResponse = {
20
4
  themes: Record<string, ThemeParsed>;
21
5
  themeManager: ThemeManager | null;
22
6
  name: string;
23
- theme: ThemeParsed | null;
24
- className?: string | undefined;
7
+ isNewTheme?: boolean;
8
+ theme?: ThemeParsed | null;
9
+ className?: string;
25
10
  };
11
+ export declare const useTheme: (props?: ThemeProps) => ThemeParsed;
12
+ export declare const getThemeManager: (theme: any) => ThemeManager | undefined;
13
+ export declare const getThemeIsNewTheme: (theme: any) => ThemeManager | undefined;
14
+ export declare const activeThemeManagers: Set<ThemeManager>;
15
+ export declare const useChangeThemeEffect: (props: ThemeProps, root?: boolean) => ChangedThemeResponse;
26
16
  //# sourceMappingURL=useTheme.d.ts.map
@@ -0,0 +1,5 @@
1
+ import { ThemeName } from '../types';
2
+ export declare function useThemeName(opts?: {
3
+ parent?: true;
4
+ }): ThemeName;
5
+ //# sourceMappingURL=useThemeName.d.ts.map