@tamagui/core 1.0.2 → 1.0.4

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 (117) hide show
  1. package/dist/cjs/config.js +1 -1
  2. package/dist/cjs/config.js.map +2 -2
  3. package/dist/cjs/createComponent.js +51 -95
  4. package/dist/cjs/createComponent.js.map +2 -2
  5. package/dist/cjs/createTamagui.js +7 -4
  6. package/dist/cjs/createTamagui.js.map +2 -2
  7. package/dist/cjs/createVariable.js +1 -1
  8. package/dist/cjs/createVariable.js.map +2 -2
  9. package/dist/cjs/createVariables.js +12 -3
  10. package/dist/cjs/createVariables.js.map +2 -2
  11. package/dist/cjs/helpers/ThemeManager.js +12 -2
  12. package/dist/cjs/helpers/ThemeManager.js.map +2 -2
  13. package/dist/cjs/helpers/getSize.js +9 -5
  14. package/dist/cjs/helpers/getSize.js.map +2 -2
  15. package/dist/cjs/helpers/getSplitStyles.js +39 -45
  16. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  17. package/dist/cjs/helpers/getStylesAtomic.js +32 -26
  18. package/dist/cjs/helpers/getStylesAtomic.js.map +2 -2
  19. package/dist/cjs/helpers/getStylesAtomic.native.js +6 -2
  20. package/dist/cjs/helpers/getStylesAtomic.native.js.map +2 -2
  21. package/dist/cjs/helpers/insertStyleRule.js +12 -1
  22. package/dist/cjs/helpers/insertStyleRule.js.map +2 -2
  23. package/dist/cjs/helpers/normalizeColor.js +8 -7
  24. package/dist/cjs/helpers/normalizeColor.js.map +2 -2
  25. package/dist/cjs/hooks/useMedia.js +37 -36
  26. package/dist/cjs/hooks/useMedia.js.map +2 -2
  27. package/dist/cjs/hooks/useTheme.js +28 -42
  28. package/dist/cjs/hooks/useTheme.js.map +3 -3
  29. package/dist/cjs/index.js +0 -1
  30. package/dist/cjs/index.js.map +2 -2
  31. package/dist/cjs/styled.js +4 -1
  32. package/dist/cjs/styled.js.map +2 -2
  33. package/dist/cjs/types.js.map +1 -1
  34. package/dist/cjs/views/Slot.js +1 -33
  35. package/dist/cjs/views/Slot.js.map +3 -3
  36. package/dist/cjs/views/Stack.test.js +4 -6
  37. package/dist/cjs/views/Stack.test.js.map +2 -2
  38. package/dist/cjs/views/Theme.js +45 -41
  39. package/dist/cjs/views/Theme.js.map +2 -2
  40. package/dist/cjs/views/ThemeProvider.js +1 -1
  41. package/dist/cjs/views/ThemeProvider.js.map +2 -2
  42. package/dist/esm/config.js +1 -1
  43. package/dist/esm/config.js.map +2 -2
  44. package/dist/esm/createComponent.js +53 -97
  45. package/dist/esm/createComponent.js.map +2 -2
  46. package/dist/esm/createTamagui.js +8 -5
  47. package/dist/esm/createTamagui.js.map +2 -2
  48. package/dist/esm/createVariable.js +1 -1
  49. package/dist/esm/createVariable.js.map +2 -2
  50. package/dist/esm/createVariables.js +10 -2
  51. package/dist/esm/createVariables.js.map +2 -2
  52. package/dist/esm/helpers/ThemeManager.js +13 -3
  53. package/dist/esm/helpers/ThemeManager.js.map +2 -2
  54. package/dist/esm/helpers/getSize.js +9 -5
  55. package/dist/esm/helpers/getSize.js.map +2 -2
  56. package/dist/esm/helpers/getSplitStyles.js +39 -45
  57. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  58. package/dist/esm/helpers/getStylesAtomic.js +31 -26
  59. package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
  60. package/dist/esm/helpers/getStylesAtomic.native.js +4 -1
  61. package/dist/esm/helpers/getStylesAtomic.native.js.map +2 -2
  62. package/dist/esm/helpers/insertStyleRule.js +12 -1
  63. package/dist/esm/helpers/insertStyleRule.js.map +2 -2
  64. package/dist/esm/helpers/normalizeColor.js +8 -7
  65. package/dist/esm/helpers/normalizeColor.js.map +2 -2
  66. package/dist/esm/hooks/useMedia.js +37 -37
  67. package/dist/esm/hooks/useMedia.js.map +2 -2
  68. package/dist/esm/hooks/useTheme.js +25 -39
  69. package/dist/esm/hooks/useTheme.js.map +3 -3
  70. package/dist/esm/index.js +0 -1
  71. package/dist/esm/index.js.map +2 -2
  72. package/dist/esm/styled.js +4 -1
  73. package/dist/esm/styled.js.map +2 -2
  74. package/dist/esm/views/Slot.js +1 -33
  75. package/dist/esm/views/Slot.js.map +3 -3
  76. package/dist/esm/views/Stack.test.js +1 -3
  77. package/dist/esm/views/Stack.test.js.map +2 -2
  78. package/dist/esm/views/Theme.js +44 -40
  79. package/dist/esm/views/Theme.js.map +2 -2
  80. package/dist/esm/views/ThemeProvider.js +1 -1
  81. package/dist/esm/views/ThemeProvider.js.map +2 -2
  82. package/package.json +11 -11
  83. package/reset.css +4 -0
  84. package/src/__snapshots__/createTokens.test.ts.snap +90 -195
  85. package/src/config.ts +1 -1
  86. package/src/createComponent.tsx +72 -152
  87. package/src/createTamagui.ts +8 -5
  88. package/src/createVariable.ts +2 -1
  89. package/src/createVariables.ts +14 -1
  90. package/src/helpers/ThemeManager.tsx +13 -3
  91. package/src/helpers/getSplitStyles.tsx +43 -53
  92. package/src/helpers/getStylesAtomic.native.ts +2 -0
  93. package/src/helpers/getStylesAtomic.ts +36 -31
  94. package/src/helpers/insertStyleRule.tsx +12 -2
  95. package/src/helpers/normalizeColor.ts +8 -7
  96. package/src/hooks/useMedia.tsx +53 -48
  97. package/src/hooks/useTheme.tsx +37 -56
  98. package/src/index.ts +0 -1
  99. package/src/styled.tsx +4 -1
  100. package/src/types.tsx +7 -3
  101. package/src/views/Slot.tsx +3 -59
  102. package/src/views/Stack.test.tsx +1 -4
  103. package/src/views/Theme.tsx +60 -54
  104. package/src/views/ThemeProvider.tsx +1 -1
  105. package/types/createVariables.d.ts +1 -0
  106. package/types/helpers/ThemeManager.d.ts +1 -1
  107. package/types/helpers/getSplitStyles.d.ts +2 -3
  108. package/types/helpers/getStylesAtomic.d.ts +1 -0
  109. package/types/helpers/getStylesAtomic.native.d.ts +1 -0
  110. package/types/hooks/useMedia.d.ts +8 -4
  111. package/types/hooks/useTheme.d.ts +16 -2
  112. package/types/index.d.ts +0 -1
  113. package/types/types.d.ts +3 -2
  114. package/types/views/Slot.d.ts +5 -4
  115. package/types/views/Theme.d.ts +5 -2
  116. package/src/helpers/cache.ts +0 -13
  117. package/src/helpers/getSize.ts +0 -23
package/src/config.ts CHANGED
@@ -18,7 +18,7 @@ export const setConfigFont = (name: string, font: any, fontParsed: any) => {
18
18
  export const getConfig = () => {
19
19
  if (!conf) {
20
20
  throw new Error(
21
- process.env.NODE_ENV === 'development'
21
+ process.env.NODE_ENV !== 'production'
22
22
  ? `Missing tamagui config, you either have a duplicate config, or haven't set it up. Be sure createTamagui is called before rendering.`
23
23
  : 'Err0'
24
24
  )
@@ -41,7 +41,7 @@ import { useShallowSetState } from './helpers/useShallowSetState'
41
41
  import { measureLayout, useElementLayout } from './hooks/useElementLayout'
42
42
  import { setMediaShouldUpdate, useMedia } from './hooks/useMedia'
43
43
  import { useServerRef, useServerState } from './hooks/useServerHooks'
44
- import { getThemeIsNewTheme, getThemeManager, useTheme } from './hooks/useTheme'
44
+ import { useThemeWithState } from './hooks/useTheme'
45
45
  import {
46
46
  DebugProp,
47
47
  SpaceDirection,
@@ -60,7 +60,7 @@ import {
60
60
  } from './types'
61
61
  import { usePressability } from './vendor/Pressability'
62
62
  import { Slot, mergeEvent } from './views/Slot'
63
- import { useThemeManagerContext } from './views/Theme'
63
+ import { useThemedChildren } from './views/Theme'
64
64
 
65
65
  // let t
66
66
  // import { timer } from '@tamagui/timer'
@@ -196,9 +196,8 @@ export function createComponent<
196
196
  const stateRef = useRef(
197
197
  undefined as any as {
198
198
  hasAnimated?: boolean
199
- hasThemeInversed?: boolean
200
- hasProvidedThemeManager?: boolean
201
- themeShouldReset?: boolean
199
+ themeShallow?: boolean
200
+ didAccessThemeVariableValue?: boolean
202
201
  }
203
202
  )
204
203
  stateRef.current ??= {}
@@ -233,19 +232,13 @@ export function createComponent<
233
232
 
234
233
  if (process.env.NODE_ENV === 'development') {
235
234
  if (debugProp) {
236
- const name = `${
237
- componentName ||
238
- Component?.displayName ||
239
- Component?.name ||
240
- '[Unnamed Component]'
241
- }`
235
+ // prettier-ignore
236
+ const name = `${componentName || Component?.displayName || Component?.name || '[Unnamed Component]'}`
242
237
  const type = isReactNative ? '(rnw)' : ''
243
238
  const dataIs = propsIn['data-is'] || ''
244
239
  const banner = `${name}${dataIs ? ` ${dataIs}` : ''} ${type}`
245
- // eslint-disable-next-line no-console
246
240
  console.group(`%c ${banner}`, 'background: yellow;')
247
241
  if (!isServer) {
248
- // eslint-disable-next-line no-console
249
242
  console.log('state', state)
250
243
  }
251
244
  }
@@ -258,17 +251,16 @@ export function createComponent<
258
251
  const shouldForcePseudo = !!propsIn.forceStyle
259
252
  const noClassNames = shouldAvoidClasses || shouldForcePseudo
260
253
 
261
- const theme = useTheme({
254
+ const themeState = useThemeWithState({
262
255
  name: props.theme,
263
256
  componentName,
264
257
  reset: props.reset,
265
258
  inverse: props.themeInverse,
266
- // @ts-expect-error internal use only
259
+ // @ts-expect-error
267
260
  disable: props['data-themeable'],
268
261
  debug: props.debug,
269
- })
270
- const themeManager = getThemeManager(theme)
271
- const themeIsNew = getThemeIsNewTheme(theme)
262
+ shouldUpdate: () => !!stateRef.current.didAccessThemeVariableValue,
263
+ })!
272
264
 
273
265
  const hasTextAncestor = !!(isWeb && isText ? useContext(TextAncestorContext) : false)
274
266
  const languageContext = isRSC ? null : useContext(FontLanguageContext)
@@ -296,7 +288,8 @@ export function createComponent<
296
288
  const mediaState = useMedia(
297
289
  // @ts-ignore, we just pass a stable object so we can get it later with
298
290
  // should match to the one used in `setMediaShouldUpdate` below
299
- stateRef
291
+ stateRef,
292
+ debugProp ? { props, staticConfig } : null
300
293
  )
301
294
 
302
295
  setDidGetVariableValue(false)
@@ -304,7 +297,7 @@ export function createComponent<
304
297
  const splitStyles = useSplitStyles(
305
298
  props,
306
299
  staticConfig,
307
- theme,
300
+ themeState.theme,
308
301
  {
309
302
  ...state,
310
303
  mediaState,
@@ -321,14 +314,17 @@ export function createComponent<
321
314
  )
322
315
 
323
316
  // only listen for changes if we are using raw theme values or media space, or dynamic media (native)
324
- const shouldListenForMediaChanges =
317
+ // array = space media breakpoints
318
+ const isMediaSpaced = Array.isArray(splitStyles.hasMedia)
319
+ const shouldListenForMedia =
325
320
  didGetVariableValue() ||
326
- splitStyles.hasMedia === 'space' ||
327
- (noClassNames === true && splitStyles.hasMedia)
321
+ isMediaSpaced ||
322
+ (noClassNames && splitStyles.hasMedia === true)
328
323
 
329
- if (shouldListenForMediaChanges) {
330
- setMediaShouldUpdate(stateRef, shouldListenForMediaChanges)
331
- }
324
+ setMediaShouldUpdate(stateRef, {
325
+ enabled: shouldListenForMedia,
326
+ keys: noClassNames && isMediaSpaced ? (splitStyles.hasMedia as any) : null,
327
+ })
332
328
 
333
329
  const hostRef = useServerRef<TamaguiElement>(null)
334
330
 
@@ -337,37 +333,27 @@ export function createComponent<
337
333
 
338
334
  if (process.env.NODE_ENV === 'development') {
339
335
  if (!process.env.TAMAGUI_TARGET) {
340
- // eslint-disable-next-line no-console
341
336
  console.error(
342
337
  `No process.env.TAMAGUI_TARGET set, please set it to "native" or "web".`
343
338
  )
344
339
  }
345
340
 
346
341
  if (debugProp) {
347
- // eslint-disable-next-line no-console
348
342
  console.groupCollapsed('props')
349
- // eslint-disable-next-line no-console
350
- console.log(
351
- 'props in',
352
- propsIn,
353
- 'mapped to',
354
- props,
355
- 'in order',
356
- Object.keys(props)
357
- )
358
- // eslint-disable-next-line no-console
343
+ // prettier-ignore
344
+ console.log('props in', propsIn, 'mapped to', props, 'in order', Object.keys(props))
359
345
  console.log('splitStyles', splitStyles)
360
346
  // eslint-disable-next-line no-console
361
- console.log('shouldListenForMediaChanges', shouldListenForMediaChanges)
347
+ console.log('shouldListenForMedia', shouldListenForMedia)
362
348
  // eslint-disable-next-line no-console
363
349
  console.log('className', Object.values(splitStyles.classNames))
364
350
  if (isClient) {
365
- // eslint-disable-next-line no-console
366
351
  console.log('ref', hostRef, '(click to view)')
367
352
  }
368
- // eslint-disable-next-line no-console
369
353
  console.groupEnd()
370
354
  if (debugProp === 'break') {
355
+ // rome-ignore lint/suspicious/noDebugger: ok
356
+ debugger
371
357
  }
372
358
  }
373
359
  }
@@ -375,7 +361,6 @@ export function createComponent<
375
361
  const {
376
362
  viewProps: viewPropsIn,
377
363
  pseudos,
378
- medias,
379
364
  style: splitStylesStyle,
380
365
  classNames,
381
366
  space,
@@ -392,7 +377,7 @@ export function createComponent<
392
377
  style: splitStylesStyle,
393
378
  presence,
394
379
  state,
395
- pseudos,
380
+ pseudos: pseudos || null,
396
381
  onDidAnimate: props.onDidAnimate,
397
382
  hostRef,
398
383
  staticConfig,
@@ -559,7 +544,6 @@ export function createComponent<
559
544
  Children.toArray(props.children).forEach((item) => {
560
545
  // allow newlines because why not its annoying with mdx
561
546
  if (typeof item === 'string' && item !== '\n') {
562
- // eslint-disable-next-line no-console
563
547
  console.error(
564
548
  `Unexpected text node: ${item}. A text node cannot be a child of a <View>.`
565
549
  )
@@ -602,10 +586,9 @@ export function createComponent<
602
586
  if (isStringElement && shouldAvoidClasses && !shouldForcePseudo) {
603
587
  styles = {
604
588
  ...(animationStyles ?? splitStylesStyle),
605
- ...medias,
606
589
  }
607
590
  } else {
608
- styles = [animationStyles ?? splitStylesStyle, medias]
591
+ styles = [animationStyles ?? splitStylesStyle]
609
592
 
610
593
  // ugly but for now...
611
594
  if (shouldForcePseudo) {
@@ -630,7 +613,6 @@ export function createComponent<
630
613
  : '',
631
614
  componentName ? componentClassName : '',
632
615
  fontFamilyClassName,
633
- themeIsNew ? theme.className : '',
634
616
  classNames ? Object.values(classNames).join(' ') : '',
635
617
  ]
636
618
 
@@ -695,12 +677,8 @@ export function createComponent<
695
677
  }
696
678
 
697
679
  const runtimePressStyle = !disabled && noClassNames && pseudos?.pressStyle
698
- const attachPress = !!(
699
- runtimePressStyle ||
700
- onPress ||
701
- onPressOut ||
702
- onPressIn ||
703
- onClick
680
+ const attachPress = Boolean(
681
+ runtimePressStyle || onPress || onPressOut || onPressIn || onClick
704
682
  )
705
683
  const runtimeHoverStyle = !disabled && noClassNames && pseudos?.hoverStyle
706
684
  const isHoverable =
@@ -711,25 +689,15 @@ export function createComponent<
711
689
 
712
690
  // check presence rather than value to prevent reparenting bugs
713
691
  // allows for onPress={x ? function : undefined} without re-ordering dom
714
- const shouldAttach = asChild
715
- ? false
716
- : Boolean(
717
- attachPress ||
718
- isHoverable ||
719
- 'pressStyle' in props ||
720
- 'onPress' in props ||
721
- 'onPressIn' in props ||
722
- 'onPressOut' in props ||
723
- (isWeb &&
724
- ('hoverStyle' in props ||
725
- 'onHoverIn' in props ||
726
- 'onHoverOut' in props ||
727
- 'onMouseEnter' in props ||
728
- 'onMouseLeave' in props))
729
- )
692
+ const shouldAttach = Boolean(
693
+ attachPress ||
694
+ isHoverable ||
695
+ (noClassNames && 'pressStyle' in props) ||
696
+ (isWeb && noClassNames && 'hoverStyle' in props)
697
+ )
730
698
 
731
699
  const events =
732
- shouldAttach && !isRSC && !isDisabled
700
+ shouldAttach && !isRSC && !isDisabled && !asChild
733
701
  ? {
734
702
  onPressOut: attachPress
735
703
  ? (e) => {
@@ -811,46 +779,10 @@ export function createComponent<
811
779
  }
812
780
  : null
813
781
 
814
- const themeShouldReset = Boolean(themeShallow && themeManager && themeIsNew)
815
- const shouldProvideThemeManager = themeShouldReset || (themeManager && themeIsNew)
816
-
817
- // memoize to avoid re-parenting
818
- if (shouldProvideThemeManager) {
819
- stateRef.current.hasProvidedThemeManager = true
820
- }
821
- if (themeShouldReset) {
822
- stateRef.current.themeShouldReset = true
823
- }
824
-
825
- const innerContent = useThemeManagerContext(
826
- spacedChildren({
827
- separator,
828
- children,
829
- space,
830
- direction: props.spaceDirection || 'both',
831
- isZStack,
832
- }),
833
- // only set context if changed theme
834
- stateRef.current.hasProvidedThemeManager ? themeManager : undefined,
835
- stateRef.current.themeShouldReset
836
- )
837
-
838
- let content = !children || asChild ? children : innerContent
839
-
840
- if (asChild) {
841
- elementType = Slot
842
- viewProps = {
843
- ...viewProps,
844
- onPress,
845
- onPressIn,
846
- onPressOut,
847
- }
848
- }
849
-
850
782
  // EVENTS native
851
783
  if (process.env.TAMAGUI_TARGET === 'native') {
852
784
  // add focus events
853
- const attachFocus = !!pseudos.focusStyle
785
+ const attachFocus = !!pseudos?.focusStyle
854
786
  if (attachFocus) {
855
787
  viewProps.onFocus = mergeEvent(viewProps.onFocus, () => {
856
788
  setStateShallow({ focus: true })
@@ -873,8 +805,38 @@ export function createComponent<
873
805
  }
874
806
  }
875
807
 
808
+ const shouldReset = !!(themeShallow && themeState.isNewTheme)
809
+ if (shouldReset) {
810
+ stateRef.current.themeShallow = true
811
+ }
812
+
813
+ let content =
814
+ !children || asChild
815
+ ? children
816
+ : spacedChildren({
817
+ separator,
818
+ children,
819
+ space,
820
+ direction: props.spaceDirection || 'both',
821
+ isZStack,
822
+ })
823
+
824
+ if (asChild) {
825
+ elementType = Slot
826
+ viewProps = {
827
+ ...viewProps,
828
+ onPress,
829
+ onPressIn,
830
+ onPressOut,
831
+ }
832
+ }
833
+
876
834
  content = createElement(elementType, viewProps, content)
877
835
 
836
+ content = useThemedChildren(themeState, content, {
837
+ shallow: stateRef.current.themeShallow,
838
+ })
839
+
878
840
  if (process.env.TAMAGUI_TARGET === 'web') {
879
841
  if (events || isAnimatedReactNativeWeb) {
880
842
  content = (
@@ -899,57 +861,16 @@ export function createComponent<
899
861
  if (process.env.NODE_ENV === 'development' && process.env.DEBUG !== 'tamagui') {
900
862
  if (debugProp) {
901
863
  const element = typeof elementType === 'string' ? elementType : 'Component'
902
- // eslint-disable-next-line no-console
903
864
  console.groupCollapsed(`render <${element} /> with props`, viewProps)
904
865
  for (const key in viewProps) {
905
- // eslint-disable-next-line no-console
906
866
  console.log(key, viewProps[key])
907
867
  }
908
- // eslint-disable-next-line no-console
909
868
  console.log('children', content)
910
- // eslint-disable-next-line no-console
911
869
  console.groupEnd()
912
870
  if (typeof window !== 'undefined') {
913
- // eslint-disable-next-line no-console
914
- console.log({
915
- state,
916
- shouldProvideThemeManager,
917
- isAnimated,
918
- isAnimatedReactNativeWeb,
919
- tamaguiDefaultProps,
920
- viewProps,
921
- splitStyles,
922
- animationStyles,
923
- handlesPressEvents,
924
- isStringElement,
925
- classNamesIn: props.className?.split(' '),
926
- classNamesOut: viewProps.className?.split(' '),
927
- events,
928
- shouldAttach,
929
- styles,
930
- pseudos,
931
- content,
932
- shouldAvoidClasses,
933
- avoidClasses: avoidClassesWhileAnimating,
934
- animation: props.animation,
935
- style: splitStylesStyle,
936
- ...(typeof window !== 'undefined'
937
- ? {
938
- theme,
939
- themeClassName: theme.className,
940
- staticConfig,
941
- tamaguiConfig,
942
- events,
943
- shouldAvoidClasses,
944
- shouldForcePseudo,
945
- classNames: Object.fromEntries(
946
- Object.entries(classNames).map(([k, v]) => [v, getAllSelectors()[v]])
947
- ),
948
- }
949
- : null),
950
- })
871
+ // prettier-ignore
872
+ console.log({ state, themeState, isAnimated, isAnimatedReactNativeWeb, tamaguiDefaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: props.className?.split(' '), classNamesOut: viewProps.className?.split(' '), events, shouldAttach, styles, pseudos, content, shouldAvoidClasses, avoidClasses: avoidClassesWhileAnimating, animation: props.animation, style: splitStylesStyle, staticConfig, tamaguiConfig, shouldForcePseudo, classNamesFull: Object.fromEntries(Object.entries(classNames).map(([k, v]) => [v, getAllSelectors()[v]])) })
951
873
  }
952
- // eslint-disable-next-line no-console
953
874
  console.groupEnd()
954
875
  }
955
876
  }
@@ -989,7 +910,6 @@ export function createComponent<
989
910
  initialTheme = proxyThemeVariables(next)
990
911
  if (process.env.NODE_ENV === 'development') {
991
912
  if (!initialTheme) {
992
- // eslint-disable-next-line no-console
993
913
  console.log('Warning: Missing theme')
994
914
  }
995
915
  }
@@ -1052,7 +972,6 @@ export function createComponent<
1052
972
  // add debug logs
1053
973
  if (process.env.NODE_ENV === 'development' && debug) {
1054
974
  if (process.env.IS_STATIC !== 'is_static') {
1055
- // eslint-disable-next-line no-console
1056
975
  console.log(`🐛 [${staticConfig.componentName || 'Component'}]`, {
1057
976
  staticConfig,
1058
977
  tamaguiDefaultProps,
@@ -1124,6 +1043,7 @@ export const Spacer = createComponent<SpacerProps>({
1124
1043
  // avoid nesting issues
1125
1044
  tag: 'span',
1126
1045
  size: true,
1046
+ pointerEvents: 'none',
1127
1047
  },
1128
1048
 
1129
1049
  variants: {
@@ -1,7 +1,8 @@
1
1
  import { isRSC, isWeb } from '@tamagui/constants'
2
2
 
3
3
  import { configListeners, setConfig } from './config'
4
- import { createVariables } from './createVariables'
4
+ import { createVariables, tokensKeysOrdered } from './createVariables'
5
+ import { startClearStyleCacheInterval } from './helpers/getStylesAtomic'
5
6
  import { getThemeCSSRules } from './helpers/getThemeCSSRules'
6
7
  import {
7
8
  getAllRules,
@@ -48,6 +49,7 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
48
49
 
49
50
  scanAllSheets()
50
51
  listenForSheetChanges()
52
+ startClearStyleCacheInterval()
51
53
 
52
54
  const fontTokens = Object.fromEntries(
53
55
  Object.entries(configIn.fonts!).map(([k, v]) => {
@@ -188,10 +190,11 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
188
190
 
189
191
  // faster $lookups
190
192
  const tokensParsed: any = Object.fromEntries(
191
- Object.entries(configIn.tokens).map(([k, v]) => [
192
- k,
193
- Object.fromEntries(Object.entries(v).map(([k, v]) => [`$${k}`, v])),
194
- ])
193
+ Object.entries(configIn.tokens).map(([k, v]) => {
194
+ const val = Object.fromEntries(Object.entries(v).map(([k, v]) => [`$${k}`, v]))
195
+ tokensKeysOrdered.set(val, tokensKeysOrdered.get(v))
196
+ return [k, val]
197
+ })
195
198
  )
196
199
 
197
200
  const shorthands = configIn.shorthands || {}
@@ -33,12 +33,12 @@ export const createVariable = <A extends string | number = any>(props: VariableI
33
33
  }
34
34
  }
35
35
 
36
+ // could do weakmap cache
36
37
  export function variableToString(vrble?: any, getValue = false) {
37
38
  if (isVariable(vrble)) {
38
39
  if (!getValue && isWeb && vrble.variable) {
39
40
  return vrble.variable
40
41
  }
41
- setDidGetVariableValue(true)
42
42
  return `${vrble.val}`
43
43
  }
44
44
  return `${vrble || ''}`
@@ -49,6 +49,7 @@ export function isVariable(v: Variable | any): v is Variable {
49
49
  }
50
50
 
51
51
  export function getVariable(nameOrVariable: Variable | string) {
52
+ setDidGetVariableValue(true)
52
53
  if (isVariable(nameOrVariable)) {
53
54
  return variableToString(nameOrVariable)
54
55
  }
@@ -14,6 +14,8 @@ export type DeepVariableObject<A extends DeepTokenObject> = {
14
14
  : never
15
15
  }
16
16
 
17
+ export const tokensKeysOrdered = new WeakMap()
18
+
17
19
  export const createVariables = <A extends DeepTokenObject>(
18
20
  tokens: A,
19
21
  parentPath = '',
@@ -21,9 +23,14 @@ export const createVariables = <A extends DeepTokenObject>(
21
23
  ): DeepVariableObject<A> => {
22
24
  const res: any = {}
23
25
  let i = 0
24
- for (const key in tokens) {
26
+ for (let key in tokens) {
25
27
  i++
26
28
  const val = tokens[key]
29
+ // always remove $ prefix
30
+ if (key[0] === '$') {
31
+ // @ts-ignore
32
+ key = key.slice(1)
33
+ }
27
34
  if (isVariable(val)) {
28
35
  res[key] = val
29
36
  continue
@@ -38,5 +45,11 @@ export const createVariables = <A extends DeepTokenObject>(
38
45
  }
39
46
  res[key] = isVariable(val) ? val : createVariable({ val, name, key: niceKey })
40
47
  }
48
+
49
+ // ordering for relative sizing for now just size/space
50
+ if (parentPath === 'size' || parentPath === 'space') {
51
+ tokensKeysOrdered.set(res, Object.keys(tokens))
52
+ }
53
+
41
54
  return res
42
55
  }
@@ -1,4 +1,4 @@
1
- import { getThemes } from '../config'
1
+ import { getThemes, getTokens } from '../config'
2
2
  import { THEME_CLASSNAME_PREFIX, THEME_NAME_SEPARATOR } from '../constants/constants'
3
3
  import { getThemeUnwrapped } from '../hooks/getThemeUnwrapped'
4
4
  import { ThemeParsed, ThemeProps } from '../types'
@@ -39,7 +39,13 @@ export class ThemeManager {
39
39
  this.updateState(props, false)
40
40
  return
41
41
  }
42
- if (!parentManager) throw `❌`
42
+ if (!parentManager) {
43
+ if (process.env.NODE_ENV !== 'production') {
44
+ console.trace()
45
+ throw new Error(`No parent manager given`)
46
+ }
47
+ throw `❌`
48
+ }
43
49
  // copy over listeners
44
50
  this.themeListeners = parentManager.themeListeners
45
51
 
@@ -125,6 +131,7 @@ export class ThemeManager {
125
131
 
126
132
  // gets value going up to parents
127
133
  getValue(key: string, state?: ThemeManagerState) {
134
+ if (!key) return
128
135
  let theme = (state || this.state).theme
129
136
  let manager = this as ThemeManager | null
130
137
  while (theme && manager) {
@@ -134,10 +141,13 @@ export class ThemeManager {
134
141
  manager = manager.parentManager
135
142
  theme = manager?.state.theme
136
143
  }
144
+ const tokens = getTokens()
145
+ if (key in tokens.color) {
146
+ return tokens.color[key]
147
+ }
137
148
  }
138
149
 
139
150
  notify() {
140
- console.log('notify', this.themeListeners.size, this.themeListeners)
141
151
  this.themeListeners.forEach((cb) => cb(this.state.name, this))
142
152
  }
143
153