@tamagui/core 1.0.1-beta.226 → 1.0.1-beta.228

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 (135) hide show
  1. package/dist/cjs/constants/platform.js +65 -0
  2. package/dist/cjs/constants/platform.js.map +7 -0
  3. package/dist/cjs/constants/platform.native.js +62 -0
  4. package/dist/cjs/constants/platform.native.js.map +7 -0
  5. package/dist/cjs/createComponent.js +22 -38
  6. package/dist/cjs/createComponent.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/helpers/ThemeManager.js +19 -12
  10. package/dist/cjs/helpers/ThemeManager.js.map +3 -3
  11. package/dist/cjs/helpers/ThemeManager.test.js +16 -0
  12. package/dist/cjs/helpers/ThemeManager.test.js.map +2 -2
  13. package/dist/cjs/helpers/assignNativePropsToWeb.js +188 -0
  14. package/dist/cjs/helpers/assignNativePropsToWeb.js.map +7 -0
  15. package/dist/cjs/helpers/assignNativePropsToWeb.native.js +30 -0
  16. package/dist/cjs/helpers/assignNativePropsToWeb.native.js.map +7 -0
  17. package/dist/cjs/helpers/calc.js +71 -0
  18. package/dist/cjs/helpers/calc.js.map +7 -0
  19. package/dist/cjs/helpers/createPropMapper.js +3 -5
  20. package/dist/cjs/helpers/createPropMapper.js.map +2 -2
  21. package/dist/cjs/helpers/createShallowUpdate.js +44 -0
  22. package/dist/cjs/helpers/createShallowUpdate.js.map +7 -0
  23. package/dist/cjs/helpers/getFont.js +66 -0
  24. package/dist/cjs/helpers/getFont.js.map +7 -0
  25. package/dist/cjs/helpers/getSplitStyles.js +85 -67
  26. package/dist/cjs/helpers/getSplitStyles.js.map +3 -3
  27. package/dist/cjs/helpers/getStackSize.js +46 -0
  28. package/dist/cjs/helpers/getStackSize.js.map +7 -0
  29. package/dist/cjs/helpers/normalizeColor.js +2 -2
  30. package/dist/cjs/helpers/normalizeColor.js.map +2 -2
  31. package/dist/cjs/helpers/startTransition.js +36 -0
  32. package/dist/cjs/helpers/startTransition.js.map +7 -0
  33. package/dist/cjs/helpers/timer.js +35 -0
  34. package/dist/cjs/helpers/timer.js.map +7 -0
  35. package/dist/cjs/helpers/validate.js +2 -0
  36. package/dist/cjs/helpers/validate.js.map +7 -0
  37. package/dist/cjs/hooks/useConstant.js +39 -0
  38. package/dist/cjs/hooks/useConstant.js.map +7 -0
  39. package/dist/cjs/hooks/useIsMounted.js +40 -0
  40. package/dist/cjs/hooks/useIsMounted.js.map +7 -0
  41. package/dist/cjs/hooks/useIsSSR.js +46 -0
  42. package/dist/cjs/hooks/useIsSSR.js.map +7 -0
  43. package/dist/cjs/hooks/usePressable.js +36 -0
  44. package/dist/cjs/hooks/usePressable.js.map +7 -0
  45. package/dist/cjs/hooks/useTheme.js +24 -20
  46. package/dist/cjs/hooks/useTheme.js.map +3 -3
  47. package/dist/cjs/hooks/useUnmountEffect.js +32 -0
  48. package/dist/cjs/hooks/useUnmountEffect.js.map +7 -0
  49. package/dist/cjs/injectStyles.js +40 -0
  50. package/dist/cjs/injectStyles.js.map +7 -0
  51. package/dist/cjs/styled.js +0 -10
  52. package/dist/cjs/styled.js.map +2 -2
  53. package/dist/cjs/types.js.map +1 -1
  54. package/dist/cjs/views/Theme.js +5 -9
  55. package/dist/cjs/views/Theme.js.map +2 -2
  56. package/dist/cjs/views/ThemeInverse.js +18 -25
  57. package/dist/cjs/views/ThemeInverse.js.map +2 -2
  58. package/dist/cjs/views/ThemeReset.js +12 -12
  59. package/dist/cjs/views/ThemeReset.js.map +2 -2
  60. package/dist/esm/constants/platform.js +30 -0
  61. package/dist/esm/constants/platform.js.map +7 -0
  62. package/dist/esm/constants/platform.native.js +28 -0
  63. package/dist/esm/constants/platform.native.js.map +7 -0
  64. package/dist/esm/createComponent.js +22 -38
  65. package/dist/esm/createComponent.js.map +2 -2
  66. package/dist/esm/createVariable.js +1 -1
  67. package/dist/esm/createVariable.js.map +2 -2
  68. package/dist/esm/helpers/ThemeManager.js +14 -7
  69. package/dist/esm/helpers/ThemeManager.js.map +2 -2
  70. package/dist/esm/helpers/ThemeManager.test.js +16 -0
  71. package/dist/esm/helpers/ThemeManager.test.js.map +2 -2
  72. package/dist/esm/helpers/assignNativePropsToWeb.js +164 -0
  73. package/dist/esm/helpers/assignNativePropsToWeb.js.map +7 -0
  74. package/dist/esm/helpers/assignNativePropsToWeb.native.js +6 -0
  75. package/dist/esm/helpers/assignNativePropsToWeb.native.js.map +7 -0
  76. package/dist/esm/helpers/calc.js +47 -0
  77. package/dist/esm/helpers/calc.js.map +7 -0
  78. package/dist/esm/helpers/createPropMapper.js +3 -5
  79. package/dist/esm/helpers/createPropMapper.js.map +2 -2
  80. package/dist/esm/helpers/createShallowUpdate.js +20 -0
  81. package/dist/esm/helpers/createShallowUpdate.js.map +7 -0
  82. package/dist/esm/helpers/getFont.js +42 -0
  83. package/dist/esm/helpers/getFont.js.map +7 -0
  84. package/dist/esm/helpers/getSplitStyles.js +85 -67
  85. package/dist/esm/helpers/getSplitStyles.js.map +3 -3
  86. package/dist/esm/helpers/getStackSize.js +22 -0
  87. package/dist/esm/helpers/getStackSize.js.map +7 -0
  88. package/dist/esm/helpers/normalizeColor.js +1 -1
  89. package/dist/esm/helpers/normalizeColor.js.map +1 -1
  90. package/dist/esm/helpers/startTransition.js +6 -0
  91. package/dist/esm/helpers/startTransition.js.map +7 -0
  92. package/dist/esm/helpers/timer.js +11 -0
  93. package/dist/esm/helpers/timer.js.map +7 -0
  94. package/dist/esm/helpers/validate.js +1 -0
  95. package/dist/esm/helpers/validate.js.map +7 -0
  96. package/dist/esm/hooks/useConstant.js +15 -0
  97. package/dist/esm/hooks/useConstant.js.map +7 -0
  98. package/dist/esm/hooks/useIsMounted.js +16 -0
  99. package/dist/esm/hooks/useIsMounted.js.map +7 -0
  100. package/dist/esm/hooks/useIsSSR.js +22 -0
  101. package/dist/esm/hooks/useIsSSR.js.map +7 -0
  102. package/dist/esm/hooks/usePressable.js +12 -0
  103. package/dist/esm/hooks/usePressable.js.map +7 -0
  104. package/dist/esm/hooks/useTheme.js +24 -20
  105. package/dist/esm/hooks/useTheme.js.map +3 -3
  106. package/dist/esm/hooks/useUnmountEffect.js +8 -0
  107. package/dist/esm/hooks/useUnmountEffect.js.map +7 -0
  108. package/dist/esm/injectStyles.js +16 -0
  109. package/dist/esm/injectStyles.js.map +7 -0
  110. package/dist/esm/styled.js +0 -10
  111. package/dist/esm/styled.js.map +2 -2
  112. package/dist/esm/views/Theme.js +5 -9
  113. package/dist/esm/views/Theme.js.map +2 -2
  114. package/dist/esm/views/ThemeInverse.js +17 -23
  115. package/dist/esm/views/ThemeInverse.js.map +2 -2
  116. package/dist/esm/views/ThemeReset.js +12 -12
  117. package/dist/esm/views/ThemeReset.js.map +2 -2
  118. package/package.json +13 -13
  119. package/src/createComponent.tsx +22 -81
  120. package/src/createVariable.ts +1 -1
  121. package/src/helpers/ThemeManager.test.tsx +17 -0
  122. package/src/helpers/ThemeManager.tsx +29 -14
  123. package/src/helpers/createPropMapper.ts +4 -5
  124. package/src/helpers/getSplitStyles.tsx +130 -91
  125. package/src/helpers/normalizeColor.ts +1 -1
  126. package/src/helpers/timer.ts +9 -0
  127. package/src/hooks/useTheme.tsx +29 -22
  128. package/src/styled.tsx +0 -12
  129. package/src/types.tsx +2 -5
  130. package/src/views/Theme.tsx +5 -9
  131. package/types/helpers/ThemeManager.d.ts +2 -2
  132. package/types/helpers/getSplitStyles.d.ts +22 -6
  133. package/types/helpers/timer.d.ts +2 -0
  134. package/types/hooks/useTheme.d.ts +0 -1
  135. package/types/types.d.ts +1 -5
@@ -48,6 +48,33 @@ import {
48
48
  } from './normalizeValueWithProperty.js'
49
49
  import { pseudoDescriptors } from './pseudoDescriptors'
50
50
 
51
+ type GetStyleResult = {
52
+ pseudos: PseudoStyles
53
+ medias: Record<MediaQueryKey, ViewStyle>
54
+ style: ViewStyle
55
+ classNames: ClassNamesObject
56
+ rulesToInsert: RulesToInsert
57
+ viewProps: StackProps & Record<string, any>
58
+ fontFamily: string | undefined
59
+ mediaKeys: string[]
60
+ }
61
+
62
+ type GetStyleState = {
63
+ style: ViewStyle
64
+ usedKeys: Record<string, number>
65
+ classNames: ClassNamesObject
66
+ flatTransforms: FlatTransforms
67
+ staticConfig: StaticConfigParsed
68
+ theme: ThemeParsed
69
+ props: Record<string, any>
70
+ viewProps: Record<string, any>
71
+ state: SplitStyleState
72
+ conf: TamaguiInternalConfig
73
+ languageContext?: FontLanguageProps
74
+ avoidDefaultProps?: boolean
75
+ avoidMergeTransform?: boolean
76
+ }
77
+
51
78
  export type SplitStyles = ReturnType<typeof getSplitStyles>
52
79
  export type ClassNamesObject = Record<string, string>
53
80
  export type SplitStyleResult = ReturnType<typeof getSplitStyles>
@@ -134,28 +161,17 @@ type TransformNamespaceKey = 'transform' | PseudoPropKeys | MediaQueryKey
134
161
 
135
162
  let conf: TamaguiInternalConfig
136
163
 
137
- type SplitStylesAndProps = {
138
- pseudos: PseudoStyles
139
- medias: Record<MediaQueryKey, ViewStyle>
140
- style: ViewStyle
141
- classNames: ClassNamesObject
142
- rulesToInsert: RulesToInsert
143
- viewProps: StackProps & Record<string, any>
144
- fontFamily: string | undefined
145
- mediaKeys: string[]
146
- }
147
-
148
164
  type StyleSplitter = (
149
165
  props: { [key: string]: any },
150
166
  staticConfig: StaticConfigParsed,
151
167
  theme: ThemeParsed,
152
168
  state: SplitStyleState,
153
- parentSplitStyles?: SplitStylesAndProps | null,
169
+ parentSplitStyles?: GetStyleResult | null,
154
170
  languageContext?: LanguageContextType,
155
171
  // web-only
156
172
  elementType?: string,
157
173
  debug?: DebugProp
158
- ) => SplitStylesAndProps
174
+ ) => GetStyleResult
159
175
 
160
176
  export const PROP_SPLIT = '-'
161
177
 
@@ -188,9 +204,19 @@ export const getSplitStyles: StyleSplitter = (
188
204
  debug
189
205
  ) => {
190
206
  conf = conf || getConfig()
207
+ const { shorthands } = conf
208
+ const {
209
+ defaultVariants,
210
+ variants,
211
+ propMapper,
212
+ isReactNative,
213
+ deoptProps,
214
+ inlineProps,
215
+ inlineWhenUnflattened,
216
+ } = staticConfig
191
217
  const validStyleProps = staticConfig.isText ? stylePropsText : validStyles
192
218
  const mediaKeys: string[] = []
193
- const viewProps: SplitStylesAndProps['viewProps'] = {}
219
+ const viewProps: GetStyleResult['viewProps'] = {}
194
220
  const pseudos: PseudoStyles = {}
195
221
  let psuedosUsed: Record<string, number> | null = null
196
222
  const medias: Record<MediaQueryKey, ViewStyle> = {}
@@ -202,7 +228,7 @@ export const getSplitStyles: StyleSplitter = (
202
228
  staticConfig.acceptsClassName && (isWeb || IS_STATIC) && !state.noClassNames
203
229
 
204
230
  let style: ViewStyle = {}
205
- let flatTransforms: FlatTransforms | undefined
231
+ const flatTransforms: FlatTransforms = {}
206
232
 
207
233
  const len = propKeys.length
208
234
  const rulesToInsert: RulesToInsert = []
@@ -214,6 +240,20 @@ export const getSplitStyles: StyleSplitter = (
214
240
  // fontFamily is our special baby, ensure we grab the latest set one always
215
241
  let fontFamily: string | undefined
216
242
 
243
+ const styleState: GetStyleState = {
244
+ classNames,
245
+ conf,
246
+ flatTransforms,
247
+ props,
248
+ state,
249
+ staticConfig,
250
+ style,
251
+ theme,
252
+ usedKeys,
253
+ viewProps,
254
+ languageContext,
255
+ }
256
+
217
257
  if (props.className) {
218
258
  for (const cn of props.className.split(' ')) {
219
259
  if (cn[0] === '_') {
@@ -222,7 +262,7 @@ export const getSplitStyles: StyleSplitter = (
222
262
  const isMedia = mediaOrPseudo[0] === '_'
223
263
  const isPseudo = mediaOrPseudo[0] === '0'
224
264
  const isMediaOrPseudo = isMedia || isPseudo
225
- let fullKey = conf.shorthands[shorthand]
265
+ let fullKey = shorthands[shorthand]
226
266
  if (isMedia) {
227
267
  // is media
228
268
  let mediaShortKey = mediaOrPseudo.slice(1)
@@ -256,13 +296,13 @@ export const getSplitStyles: StyleSplitter = (
256
296
  const valInit = props[keyInit]
257
297
 
258
298
  // normalize shorthands up front
259
- const expandedKey = conf.shorthands[keyInit]
299
+ const expandedKey = keyInit in shorthands
260
300
  if (expandedKey) {
261
- keyInit = expandedKey
301
+ keyInit = shorthands[keyInit]
262
302
  }
263
303
 
264
- if (usedKeys[keyInit]) continue
265
- if (skipProps[keyInit]) continue
304
+ if (keyInit in usedKeys) continue
305
+ if (keyInit in skipProps) continue
266
306
  if (!isWeb && keyInit.startsWith('data-')) continue
267
307
 
268
308
  if (validStyleProps[keyInit] || keyInit.includes('-')) {
@@ -293,23 +333,6 @@ export const getSplitStyles: StyleSplitter = (
293
333
  continue
294
334
  }
295
335
 
296
- function mergeStyle(key: string, val: any) {
297
- usedKeys[key] = usedKeys[key] || 1
298
- if (val && val[0] === '_') {
299
- classNames[key] = val
300
- } else if (key in stylePropsTransform) {
301
- flatTransforms ||= {}
302
- flatTransforms[key] = val
303
- } else {
304
- const out = normalizeValueWithProperty(val, key)
305
- if (key in validStylesOnBaseProps) {
306
- viewProps[key] = out
307
- } else {
308
- style[key] = out
309
- }
310
- }
311
- }
312
-
313
336
  if (process.env.TAMAGUI_TARGET === 'web') {
314
337
  /**
315
338
  * Copying in the accessibility/prop handling from react-native-web here
@@ -328,14 +351,14 @@ export const getSplitStyles: StyleSplitter = (
328
351
  ) {
329
352
  viewProps.disabled = true
330
353
  }
331
- if (!staticConfig.variants?.disabled) {
354
+ if (!variants?.disabled) {
332
355
  continue
333
356
  }
334
357
  }
335
358
 
336
359
  if (keyInit === 'testID') {
337
360
  usedKeys[keyInit] = 1
338
- if (staticConfig.isReactNative) {
361
+ if (isReactNative) {
339
362
  viewProps.testId = valInit
340
363
  } else {
341
364
  viewProps['data-testid'] = valInit
@@ -345,7 +368,7 @@ export const getSplitStyles: StyleSplitter = (
345
368
 
346
369
  if (keyInit === 'id' || keyInit === 'nativeID') {
347
370
  usedKeys[keyInit] = 1
348
- if (staticConfig.isReactNative) {
371
+ if (isReactNative) {
349
372
  viewProps.nativeID = valInit
350
373
  } else {
351
374
  viewProps.id = valInit
@@ -355,7 +378,7 @@ export const getSplitStyles: StyleSplitter = (
355
378
 
356
379
  let didUseKeyInit = true
357
380
 
358
- if (staticConfig.isReactNative) {
381
+ if (isReactNative) {
359
382
  didUseKeyInit = false
360
383
  // pass along to react-native-web
361
384
  if (accessibilityDirectMap[keyInit] || keyInit.startsWith('accessibility')) {
@@ -455,10 +478,10 @@ export const getSplitStyles: StyleSplitter = (
455
478
  }
456
479
 
457
480
  if (
458
- (staticConfig.defaultVariants && keyInit in staticConfig.defaultVariants) ||
481
+ (defaultVariants && keyInit in defaultVariants) ||
459
482
  // may want to just: not compile styled() into classnames, always do this, and always pass in all values in extras.props
460
483
  // but we'd want to add styled({ extracted: true }) or something at compile time to save on parsing a bit...
461
- (state.keepVariantsAsProps && staticConfig.variants && keyInit in staticConfig.variants)
484
+ (state.keepVariantsAsProps && variants && keyInit in variants)
462
485
  ) {
463
486
  viewProps[keyInit] = valInit
464
487
  }
@@ -476,9 +499,9 @@ export const getSplitStyles: StyleSplitter = (
476
499
  if (
477
500
  !isMedia &&
478
501
  !isPseudo &&
479
- !staticConfig.variants?.[keyInit] &&
502
+ !variants?.[keyInit] &&
480
503
  !validStyleProps[keyInit] &&
481
- !conf.shorthands[keyInit]
504
+ !shorthands[keyInit]
482
505
  ) {
483
506
  // web-only, exclude all other accessibility props not handled above
484
507
  if (isWeb && keyInit.includes('ccessibility')) {
@@ -497,16 +520,7 @@ export const getSplitStyles: StyleSplitter = (
497
520
  const expanded =
498
521
  isMedia || isPseudo
499
522
  ? [[keyInit, valInit]]
500
- : staticConfig.propMapper(
501
- keyInit,
502
- valInit,
503
- theme,
504
- props,
505
- state,
506
- languageContext,
507
- undefined,
508
- debug
509
- )
523
+ : propMapper(keyInit, valInit, theme, props, state, languageContext, undefined, debug)
510
524
 
511
525
  if (!fontFamily) {
512
526
  fontFamily = getPropMappedFontFamily(expanded)
@@ -534,11 +548,7 @@ export const getSplitStyles: StyleSplitter = (
534
548
  continue
535
549
  }
536
550
 
537
- if (
538
- staticConfig.deoptProps?.has(key) ||
539
- staticConfig.inlineProps?.has(key) ||
540
- staticConfig.inlineWhenUnflattened?.has(key)
541
- ) {
551
+ if (deoptProps?.has(key) || inlineProps?.has(key) || inlineWhenUnflattened?.has(key)) {
542
552
  usedKeys[key] = 1
543
553
  viewProps[key] = props[key] ?? val
544
554
  }
@@ -548,18 +558,7 @@ export const getSplitStyles: StyleSplitter = (
548
558
  if (!val) continue
549
559
 
550
560
  // TODO can avoid processing this if !shouldDoClasses + state is off
551
- const pseudoStyleObject = getSubStyle(
552
- key,
553
- val,
554
- staticConfig,
555
- theme,
556
- props,
557
- state,
558
- conf,
559
- languageContext,
560
- true,
561
- true
562
- )
561
+ const pseudoStyleObject = getSubStyle(styleState, key, val, true, state.noClassNames)
563
562
 
564
563
  const descriptor = pseudoDescriptors[key as keyof typeof pseudoDescriptors]
565
564
  const isEnter = descriptor.name === 'enter'
@@ -590,20 +589,32 @@ export const getSplitStyles: StyleSplitter = (
590
589
  }
591
590
  }
592
591
  } else {
593
- if (!state[descriptor.stateKey || descriptor.name]) {
594
- continue
592
+ const isDisabled = !state[descriptor.stateKey || descriptor.name]
593
+ if (!isDisabled) {
594
+ usedKeys[key] ||= 1
595
595
  }
596
596
  psuedosUsed ||= {}
597
- usedKeys[key] ||= 1
597
+
598
598
  const importance = descriptor.priority
599
599
  for (const pkey in pseudoStyleObject) {
600
- const curImportance = psuedosUsed[importance] || 0
601
600
  const val = pseudoStyleObject[pkey]
601
+ // when disabled ensure the default value is set for future animations to align
602
+ if (isDisabled) {
603
+ if (!(pkey in usedKeys) && pkey in animatableDefaults) {
604
+ const defaultVal = animatableDefaults[pkey]
605
+ mergeStyle(styleState, pkey, defaultVal, true)
606
+ }
607
+ continue
608
+ }
609
+ const curImportance = psuedosUsed[importance] || 0
602
610
  if (importance >= curImportance) {
603
611
  psuedosUsed[pkey] = importance
604
612
  pseudos[key] ||= {}
605
613
  pseudos[key][pkey] = val
606
- mergeStyle(pkey, val)
614
+ // prettier-ignore
615
+ // eslint-disable-next-line no-console
616
+ if (process.env.NODE_ENV === 'development' && debug === 'verbose') console.log('merging', pkey, val)
617
+ mergeStyle(styleState, pkey, val)
607
618
  }
608
619
  }
609
620
  }
@@ -622,14 +633,9 @@ export const getSplitStyles: StyleSplitter = (
622
633
  // we avoid passing in default props for media queries because that would confuse things like SizableText.size:
623
634
 
624
635
  const mediaStyle = getSubStyle(
636
+ styleState,
625
637
  key,
626
638
  val,
627
- staticConfig,
628
- theme,
629
- props,
630
- state,
631
- conf,
632
- languageContext,
633
639
  // TODO try true like pseudo
634
640
  false
635
641
  )
@@ -675,12 +681,12 @@ export const getSplitStyles: StyleSplitter = (
675
681
  }
676
682
 
677
683
  if (validStyleProps[key]) {
678
- mergeStyle(key, val)
684
+ mergeStyle(styleState, key, val)
679
685
  continue
680
686
  }
681
687
 
682
688
  // pass to view props
683
- if (!staticConfig.variants || !(key in staticConfig.variants)) {
689
+ if (!variants || !(key in variants)) {
684
690
  if (!skipProps[key]) {
685
691
  viewProps[key] = val
686
692
  usedKeys[key] = 1
@@ -697,6 +703,11 @@ export const getSplitStyles: StyleSplitter = (
697
703
  // always do this at the very end to preserve the order strictly (animations, origin)
698
704
  // and allow proper merging of all pseudos before applying
699
705
  if (flatTransforms) {
706
+ if (process.env.NODE_ENV === 'development' && debug) {
707
+ // prettier-ignore
708
+ // eslint-disable-next-line no-console
709
+ console.log(`Merging flat transforms, transform before`, [...style.transform || []], flatTransforms)
710
+ }
700
711
  mergeTransforms(style, flatTransforms, true)
701
712
  }
702
713
 
@@ -864,18 +875,38 @@ function getSubStyleProps(defaultProps: Object, baseProps: Object, specificProps
864
875
  return cache.get(key)!
865
876
  }
866
877
 
878
+ function mergeStyle(
879
+ { usedKeys, classNames, flatTransforms, viewProps, style }: GetStyleState,
880
+ key: string,
881
+ val: any,
882
+ dontSetUsed = false
883
+ ) {
884
+ if (!dontSetUsed) {
885
+ usedKeys[key] = usedKeys[key] || 1
886
+ }
887
+ if (val && val[0] === '_') {
888
+ classNames[key] = val
889
+ } else if (key in stylePropsTransform) {
890
+ flatTransforms ||= {}
891
+ flatTransforms[key] = val
892
+ } else {
893
+ const out = normalizeValueWithProperty(val, key)
894
+ if (key in validStylesOnBaseProps) {
895
+ viewProps[key] = out
896
+ } else {
897
+ style[key] = out
898
+ }
899
+ }
900
+ }
901
+
867
902
  export const getSubStyle = (
903
+ styleState: GetStyleState,
868
904
  subKey: string,
869
905
  styleIn: Object,
870
- staticConfig: StaticConfigParsed,
871
- theme: ThemeParsed,
872
- props: any,
873
- state: SplitStyleState,
874
- conf: TamaguiInternalConfig,
875
- languageContext?: FontLanguageProps,
876
906
  avoidDefaultProps?: boolean,
877
907
  avoidMergeTransform?: boolean
878
908
  ): ViewStyle => {
909
+ const { staticConfig, theme, props, state, conf, languageContext } = styleState
879
910
  const styleOut: ViewStyle = {}
880
911
 
881
912
  for (let key in styleIn) {
@@ -939,3 +970,11 @@ function addStyleToInsertRules(rulesToInsert: RulesToInsert, styleObject: Partia
939
970
  function processIDRefList(idRefList: string | Array<string>): string {
940
971
  return Array.isArray(idRefList) ? idRefList.join(' ') : idRefList
941
972
  }
973
+
974
+ const animatableDefaults = {
975
+ opacity: 1,
976
+ scale: 1,
977
+ rotate: '0deg',
978
+ rotateY: '0deg',
979
+ rotateX: '0deg',
980
+ }
@@ -1,4 +1,4 @@
1
- import normalizeCSSColor from '@tamagui/normalize-css-color-lite'
1
+ import normalizeCSSColor from 'normalize-css-color'
2
2
 
3
3
  export const normalizeColor = (color?: number | string | null, opacity?: number) => {
4
4
  if (color == null || color == undefined) {
@@ -0,0 +1,9 @@
1
+ const timer = require('@tamagui/timer').timer()
2
+
3
+ setTimeout(() => {
4
+ timer.print()
5
+ }, 2000)
6
+
7
+ export const time = timer.start({
8
+ quiet: true,
9
+ })
@@ -11,7 +11,6 @@ import { ThemeParsed, ThemeProps } from '../types'
11
11
  import { GetThemeUnwrapped } from './getThemeUnwrapped'
12
12
 
13
13
  export type ChangedThemeResponse = {
14
- themes: Record<string, ThemeParsed>
15
14
  themeManager: ThemeManager | null
16
15
  name: string
17
16
  isNewTheme?: boolean
@@ -20,17 +19,22 @@ export type ChangedThemeResponse = {
20
19
  }
21
20
 
22
21
  const emptyProps = { name: null }
22
+
23
+ function getDefaultThemeProxied() {
24
+ const config = getConfig()
25
+ const name = Object.keys(config.themes)[0]
26
+ return getThemeProxied({
27
+ theme: config.themes[name],
28
+ name,
29
+ })
30
+ }
31
+
23
32
  export const useTheme = (props: ThemeProps = emptyProps): ThemeParsed => {
24
33
  if (isRSC) {
25
- const config = getConfig()
26
- const name = Object.keys(config.themes)[0]
27
- return getThemeProxied({
28
- theme: config.themes[name],
29
- name,
30
- })
34
+ return getDefaultThemeProxied()
31
35
  }
32
36
 
33
- const { name, theme, themes, themeManager, className, isNewTheme } = useChangeThemeEffect(props)
37
+ const { name, theme, themeManager, className, isNewTheme } = useChangeThemeEffect(props)
34
38
 
35
39
  if (process.env.NODE_ENV === 'development') {
36
40
  // ensure we aren't creating too many ThemeManagers
@@ -53,7 +57,7 @@ export const useTheme = (props: ThemeProps = emptyProps): ThemeParsed => {
53
57
  if (process.env.NODE_ENV === 'development') {
54
58
  console.warn('No theme found', name, props, themeManager)
55
59
  }
56
- return themes[Object.keys(themes)[0]]
60
+ return getDefaultThemeProxied()
57
61
  }
58
62
 
59
63
  return useMemo(() => {
@@ -121,26 +125,26 @@ export const getThemeIsNewTheme = (theme: any): ThemeManager | undefined => them
121
125
  export const activeThemeManagers = new Set<ThemeManager>()
122
126
 
123
127
  export const useChangeThemeEffect = (props: ThemeProps, root = false): ChangedThemeResponse => {
124
- const parentManager = useContext(ThemeManagerContext)
125
- const config = getConfig()
126
- const { debug } = props
127
- // @ts-expect-error internal use only
128
- const disable = props.disable
129
- const { themes } = config
130
128
  if (isRSC) {
131
129
  // we need context working for this to work well
132
130
  return {
133
131
  ...createState().state,
134
- themes,
135
132
  themeManager: null,
136
133
  }
137
134
  }
135
+ const parentManager = useContext(ThemeManagerContext)
136
+
137
+ const {
138
+ debug,
139
+ // @ts-expect-error internal use only
140
+ disable,
141
+ } = props
142
+
138
143
  if (disable) {
139
144
  if (!parentManager) throw new Error(`Disable topmost`)
140
145
  return {
141
146
  ...parentManager.state,
142
147
  isNewTheme: false,
143
- themes,
144
148
  themeManager: parentManager,
145
149
  }
146
150
  }
@@ -189,10 +193,11 @@ export const useChangeThemeEffect = (props: ThemeProps, root = false): ChangedTh
189
193
 
190
194
  // this seems unnecessary
191
195
  if (hasNoThemeUpdatingProps(props)) {
192
- if (!parentManager) throw new Error(`Nada`)
196
+ if (!parentManager) throw `impossible`
197
+ // prettier-ignore
198
+ if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') console.log('useTheme no updating props', parentManager.state)
193
199
  return {
194
200
  ...parentManager.state,
195
- themes,
196
201
  themeManager: parentManager,
197
202
  isNewTheme: false,
198
203
  }
@@ -202,13 +207,12 @@ export const useChangeThemeEffect = (props: ThemeProps, root = false): ChangedTh
202
207
  updateState()
203
208
 
204
209
  if (!mounted && !parentManager) {
205
- throw new Error(`Impossible`)
210
+ throw `impossible`
206
211
  }
207
212
 
208
213
  return {
209
214
  ...state,
210
215
  isNewTheme,
211
- themes,
212
216
  themeManager,
213
217
  ...(!mounted &&
214
218
  parentManager && {
@@ -235,8 +239,11 @@ export const useChangeThemeEffect = (props: ThemeProps, root = false): ChangedTh
235
239
  }
236
240
 
237
241
  function updateState() {
238
- if (themeManager.getStateIfChanged(props, state, parentManager)) {
242
+ if (themeManager.getStateIfChanged(props, isNewTheme ? state : null, parentManager)) {
239
243
  setThemeState(createState)
244
+ } else {
245
+ // prettier-ignore
246
+ if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') console.log(`useTheme updateState didn't change`)
240
247
  }
241
248
  }
242
249
  }
package/src/styled.tsx CHANGED
@@ -63,18 +63,6 @@ export function styled<
63
63
  const parentStaticConfig =
64
64
  'staticConfig' in Component ? (Component.staticConfig as StaticConfig) : null
65
65
 
66
- if (process.env.NODE_ENV === 'development') {
67
- if (parentStaticConfig?.isHOC) {
68
- // eslint-disable-next-line no-console
69
- console.warn(
70
- `Warning: Parent component is a functional component, not a Tamagui styled() component. Extending with styled() will break and lead to incorrect styles.`,
71
- `Given options:`,
72
- options,
73
- new Error().stack
74
- )
75
- }
76
- }
77
-
78
66
  if (options) {
79
67
  const {
80
68
  variants,
package/src/types.tsx CHANGED
@@ -538,6 +538,8 @@ export type ThemeValueGet<K extends string | number | symbol> = K extends 'theme
538
538
  ? FontTokens
539
539
  : K extends FontSizeKeys
540
540
  ? FontSizeTokens
541
+ : K extends `${`border${string | ''}Radius`}`
542
+ ? RadiusTokens
541
543
  : K extends SpaceKeys
542
544
  ? K extends 'shadowOffset'
543
545
  ? { width: SpaceTokens; height: SpaceTokens }
@@ -810,11 +812,6 @@ export type StaticConfig = StaticConfigPublic & {
810
812
  */
811
813
  memo?: boolean
812
814
 
813
- /**
814
- * Used internally to handle extractable HoC separate
815
- */
816
- isHOC?: boolean
817
-
818
815
  /**
819
816
  * Used insternally to attach default props to names
820
817
  */
@@ -14,14 +14,10 @@ export function Theme(props: ThemeProps) {
14
14
  }
15
15
 
16
16
  const isRoot = !!props['_isRoot']
17
- const { name, theme, themeManager, themes, isNewTheme, className } = useChangeThemeEffect(
18
- props,
19
- isRoot
20
- )
17
+ const { name, theme, themeManager, isNewTheme, className } = useChangeThemeEffect(props, isRoot)
21
18
 
22
19
  const disableThemeClass = props.disableThemeClass
23
- const missingTheme = !themes || !name || !theme
24
- const disablePassingTheme = missingTheme || !isNewTheme
20
+ const missingTheme = !name || !theme
25
21
 
26
22
  // memo here, changing theme without re-rendering all children is a critical optimization
27
23
  // may require some effort of end user to memoize but without this memo they'd have no option
@@ -30,8 +26,8 @@ export function Theme(props: ThemeProps) {
30
26
  ? React.cloneElement(props.children, { ['data-themeable']: true })
31
27
  : props.children
32
28
 
33
- return disablePassingTheme ? next : wrapThemeManagerContext(next, themeManager)
34
- }, [disablePassingTheme, props.children, themeManager])
29
+ return missingTheme ? next : wrapThemeManagerContext(next, themeManager)
30
+ }, [missingTheme, props.children, themeManager])
35
31
 
36
32
  if (process.env.NODE_ENV === 'development' && missingTheme) {
37
33
  // eslint-disable-next-line no-console
@@ -39,7 +35,7 @@ export function Theme(props: ThemeProps) {
39
35
  return props.children
40
36
  }
41
37
 
42
- if (disableThemeClass || disablePassingTheme) {
38
+ if (disableThemeClass || missingTheme) {
43
39
  return contents
44
40
  }
45
41
 
@@ -24,8 +24,8 @@ export declare class ThemeManager {
24
24
  updateState(props?: ThemeProps & {
25
25
  forceTheme?: ThemeParsed;
26
26
  }, notify?: boolean): ThemeManagerState | undefined;
27
- getStateIfChanged(props?: ThemeProps, state?: ThemeManagerState, parentManager?: ThemeManager | null): ThemeManagerState | null;
28
- getState(props?: ThemeProps): ThemeManagerState | null;
27
+ getStateIfChanged(props?: ThemeProps, state?: ThemeManagerState | null, parentManager?: ThemeManager | null): ThemeManagerState | null | undefined;
28
+ getState(props?: ThemeProps, parentManager?: ThemeManager | null): ThemeManagerState | undefined;
29
29
  get allKeys(): Set<string>;
30
30
  getValue(key: string, state?: ThemeManagerState): import("..").Variable<any> | undefined;
31
31
  notify(): void;
@@ -2,10 +2,8 @@ import type { ViewStyle } from '@tamagui/types-react-native';
2
2
  import type { DebugProp, MediaQueryKey, PseudoStyles, SplitStyleState, StackProps, StaticConfigParsed, TamaguiInternalConfig, ThemeParsed } from '../types';
3
3
  import { FontLanguageProps, LanguageContextType } from '../views/FontLanguage.types';
4
4
  import { RulesToInsert } from './insertStyleRule';
5
- export declare type SplitStyles = ReturnType<typeof getSplitStyles>;
6
- export declare type ClassNamesObject = Record<string, string>;
7
- export declare type SplitStyleResult = ReturnType<typeof getSplitStyles>;
8
- declare type SplitStylesAndProps = {
5
+ import { FlatTransforms } from './mergeTransform';
6
+ declare type GetStyleResult = {
9
7
  pseudos: PseudoStyles;
10
8
  medias: Record<MediaQueryKey, ViewStyle>;
11
9
  style: ViewStyle;
@@ -15,12 +13,30 @@ declare type SplitStylesAndProps = {
15
13
  fontFamily: string | undefined;
16
14
  mediaKeys: string[];
17
15
  };
16
+ declare type GetStyleState = {
17
+ style: ViewStyle;
18
+ usedKeys: Record<string, number>;
19
+ classNames: ClassNamesObject;
20
+ flatTransforms: FlatTransforms;
21
+ staticConfig: StaticConfigParsed;
22
+ theme: ThemeParsed;
23
+ props: Record<string, any>;
24
+ viewProps: Record<string, any>;
25
+ state: SplitStyleState;
26
+ conf: TamaguiInternalConfig;
27
+ languageContext?: FontLanguageProps;
28
+ avoidDefaultProps?: boolean;
29
+ avoidMergeTransform?: boolean;
30
+ };
31
+ export declare type SplitStyles = ReturnType<typeof getSplitStyles>;
32
+ export declare type ClassNamesObject = Record<string, string>;
33
+ export declare type SplitStyleResult = ReturnType<typeof getSplitStyles>;
18
34
  declare type StyleSplitter = (props: {
19
35
  [key: string]: any;
20
- }, staticConfig: StaticConfigParsed, theme: ThemeParsed, state: SplitStyleState, parentSplitStyles?: SplitStylesAndProps | null, languageContext?: LanguageContextType, elementType?: string, debug?: DebugProp) => SplitStylesAndProps;
36
+ }, staticConfig: StaticConfigParsed, theme: ThemeParsed, state: SplitStyleState, parentSplitStyles?: GetStyleResult | null, languageContext?: LanguageContextType, elementType?: string, debug?: DebugProp) => GetStyleResult;
21
37
  export declare const PROP_SPLIT = "-";
22
38
  export declare const getSplitStyles: StyleSplitter;
23
- export declare const getSubStyle: (subKey: string, styleIn: Object, staticConfig: StaticConfigParsed, theme: ThemeParsed, props: any, state: SplitStyleState, conf: TamaguiInternalConfig, languageContext?: FontLanguageProps, avoidDefaultProps?: boolean, avoidMergeTransform?: boolean) => ViewStyle;
39
+ export declare const getSubStyle: (styleState: GetStyleState, subKey: string, styleIn: Object, avoidDefaultProps?: boolean, avoidMergeTransform?: boolean) => ViewStyle;
24
40
  export declare const insertSplitStyles: StyleSplitter;
25
41
  export declare const useSplitStyles: StyleSplitter;
26
42
  export {};
@@ -0,0 +1,2 @@
1
+ export declare const time: any;
2
+ //# sourceMappingURL=timer.d.ts.map