@tamagui/web 1.68.6 → 1.69.1

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 (65) hide show
  1. package/dist/cjs/createComponent.js +44 -25
  2. package/dist/cjs/createComponent.js.map +1 -1
  3. package/dist/cjs/createComponent.native.js +12 -17
  4. package/dist/cjs/createComponent.native.js.map +1 -1
  5. package/dist/cjs/helpers/createStyledContext.js +15 -5
  6. package/dist/cjs/helpers/createStyledContext.js.map +2 -2
  7. package/dist/cjs/helpers/createStyledContext.native.js +15 -5
  8. package/dist/cjs/helpers/createStyledContext.native.js.map +2 -2
  9. package/dist/cjs/helpers/getSplitStyles.js +35 -28
  10. package/dist/cjs/helpers/getSplitStyles.js.map +1 -1
  11. package/dist/cjs/helpers/getSplitStyles.native.js +18 -11
  12. package/dist/cjs/helpers/getSplitStyles.native.js.map +1 -1
  13. package/dist/cjs/helpers/propMapper.js +11 -9
  14. package/dist/cjs/helpers/propMapper.js.map +1 -1
  15. package/dist/cjs/helpers/propMapper.native.js +11 -9
  16. package/dist/cjs/helpers/propMapper.native.js.map +1 -1
  17. package/dist/cjs/hooks/useMedia.js +3 -37
  18. package/dist/cjs/hooks/useMedia.js.map +1 -1
  19. package/dist/cjs/hooks/useMedia.native.js +3 -37
  20. package/dist/cjs/hooks/useMedia.native.js.map +1 -1
  21. package/dist/cjs/hooks/useProps.js +40 -6
  22. package/dist/cjs/hooks/useProps.js.map +1 -1
  23. package/dist/cjs/hooks/useProps.native.js +40 -6
  24. package/dist/cjs/hooks/useProps.native.js.map +1 -1
  25. package/dist/cjs/index.js +1 -5
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/index.native.js +1 -5
  28. package/dist/cjs/index.native.js.map +1 -1
  29. package/dist/esm/createComponent.js +44 -25
  30. package/dist/esm/createComponent.js.map +1 -1
  31. package/dist/esm/helpers/createStyledContext.js +16 -6
  32. package/dist/esm/helpers/createStyledContext.js.map +2 -2
  33. package/dist/esm/helpers/getSplitStyles.js +35 -28
  34. package/dist/esm/helpers/getSplitStyles.js.map +1 -1
  35. package/dist/esm/helpers/propMapper.js +11 -9
  36. package/dist/esm/helpers/propMapper.js.map +1 -1
  37. package/dist/esm/hooks/useMedia.js +2 -37
  38. package/dist/esm/hooks/useMedia.js.map +1 -1
  39. package/dist/esm/hooks/useProps.js +42 -5
  40. package/dist/esm/hooks/useProps.js.map +1 -1
  41. package/dist/esm/index.js +1 -4
  42. package/dist/esm/index.js.map +1 -1
  43. package/package.json +9 -9
  44. package/src/createComponent.tsx +64 -45
  45. package/src/helpers/createStyledContext.tsx +32 -9
  46. package/src/helpers/getSplitStyles.tsx +213 -198
  47. package/src/helpers/propMapper.ts +49 -41
  48. package/src/hooks/useMedia.tsx +1 -74
  49. package/src/hooks/useProps.tsx +81 -14
  50. package/src/index.ts +0 -2
  51. package/src/types.tsx +17 -2
  52. package/types/createComponent.d.ts.map +1 -1
  53. package/types/helpers/createStyledContext.d.ts +8 -3
  54. package/types/helpers/createStyledContext.d.ts.map +1 -1
  55. package/types/helpers/getSplitStyles.d.ts.map +1 -1
  56. package/types/helpers/propMapper.d.ts.map +1 -1
  57. package/types/hooks/useMedia.d.ts +1 -17
  58. package/types/hooks/useMedia.d.ts.map +1 -1
  59. package/types/hooks/useProps.d.ts +28 -9
  60. package/types/hooks/useProps.d.ts.map +1 -1
  61. package/types/index.d.ts +1 -2
  62. package/types/index.d.ts.map +1 -1
  63. package/types/types.d.ts +16 -2
  64. package/types/types.d.ts.map +1 -1
  65. package/src/hooks/useStyle.tsx +0 -48
@@ -29,7 +29,6 @@ import {
29
29
  mediaState as globalMediaState,
30
30
  isMediaKey,
31
31
  mediaKeyMatch,
32
- mediaKeyToQuery,
33
32
  mediaQueryConfig,
34
33
  mergeMediaByImportance,
35
34
  } from '../hooks/useMedia'
@@ -53,7 +52,6 @@ import type {
53
52
  ThemeParsed,
54
53
  ViewStyleWithPseudos,
55
54
  } from '../types'
56
- import type { LanguageContextType } from '../views/FontLanguage.types'
57
55
  import { createMediaStyle } from './createMediaStyle'
58
56
  import { fixStyles } from './expandStyles'
59
57
  import { getGroupPropParts } from './getGroupPropParts'
@@ -193,7 +191,7 @@ export const getSplitStyles: StyleSplitter = (
193
191
  isClient
194
192
  ) {
195
193
  console.groupCollapsed('getSplitStyles (collapsed)')
196
-
194
+
197
195
  // biome-ignore lint/suspicious/noConsoleLog: ok
198
196
  console.log({
199
197
  props,
@@ -203,7 +201,7 @@ export const getSplitStyles: StyleSplitter = (
203
201
  componentState,
204
202
  styleState,
205
203
  theme: { ...theme },
206
- });
204
+ })
207
205
  console.groupEnd()
208
206
  }
209
207
 
@@ -243,8 +241,10 @@ export const getSplitStyles: StyleSplitter = (
243
241
  let valInit = props[keyOg]
244
242
 
245
243
  // normalize shorthands up front
246
- if (keyInit in shorthands) {
247
- keyInit = shorthands[keyInit]
244
+ if (!styleProps.disableExpandShorthands) {
245
+ if (keyInit in shorthands) {
246
+ keyInit = shorthands[keyInit]
247
+ }
248
248
  }
249
249
 
250
250
  if (keyInit === 'className') continue // handled above
@@ -354,142 +354,144 @@ export const getSplitStyles: StyleSplitter = (
354
354
  }
355
355
 
356
356
  if (process.env.TAMAGUI_TARGET === 'web') {
357
- /**
358
- * Copying in the accessibility/prop handling from react-native-web here
359
- * Keeps it in a single loop, avoids dup de-structuring to avoid bundle size
360
- */
361
-
362
- if (keyInit === 'disabled' && valInit === true) {
363
- viewProps['aria-disabled'] = true
364
- // Enhance with native semantics
365
- if (
366
- elementType === 'button' ||
367
- elementType === 'form' ||
368
- elementType === 'input' ||
369
- elementType === 'select' ||
370
- elementType === 'textarea'
371
- ) {
372
- viewProps.disabled = true
373
- }
374
- if (!variants?.disabled) {
375
- continue
357
+ if (!styleProps.noExpand) {
358
+ /**
359
+ * Copying in the accessibility/prop handling from react-native-web here
360
+ * Keeps it in a single loop, avoids dup de-structuring to avoid bundle size
361
+ */
362
+
363
+ if (keyInit === 'disabled' && valInit === true) {
364
+ viewProps['aria-disabled'] = true
365
+ // Enhance with native semantics
366
+ if (
367
+ elementType === 'button' ||
368
+ elementType === 'form' ||
369
+ elementType === 'input' ||
370
+ elementType === 'select' ||
371
+ elementType === 'textarea'
372
+ ) {
373
+ viewProps.disabled = true
374
+ }
375
+ if (!variants?.disabled) {
376
+ continue
377
+ }
376
378
  }
377
- }
378
-
379
- if (keyInit === 'testID') {
380
- viewProps[isReactNative ? keyInit : 'data-testid'] = valInit
381
- continue
382
- }
383
379
 
384
- if (keyInit === 'id' || keyInit === 'nativeID') {
385
- if (isReactNative) {
386
- viewProps.nativeID = valInit
387
- } else {
388
- viewProps.id = valInit
380
+ if (keyInit === 'testID') {
381
+ viewProps[isReactNative ? keyInit : 'data-testid'] = valInit
382
+ continue
389
383
  }
390
- continue
391
- }
392
-
393
- let didUseKeyInit = false
394
384
 
395
- if (isReactNative) {
396
- // pass along to react-native-web
397
- if (keyInit in accessibilityDirectMap || keyInit.startsWith('accessibility')) {
398
- viewProps[keyInit] = valInit
385
+ if (keyInit === 'id' || keyInit === 'nativeID') {
386
+ if (isReactNative) {
387
+ viewProps.nativeID = valInit
388
+ } else {
389
+ viewProps.id = valInit
390
+ }
399
391
  continue
400
392
  }
401
- } else {
402
- didUseKeyInit = true
403
393
 
404
- if (keyInit in accessibilityDirectMap) {
405
- viewProps[accessibilityDirectMap[keyInit]] = valInit
406
- continue
394
+ let didUseKeyInit = false
395
+
396
+ if (isReactNative) {
397
+ // pass along to react-native-web
398
+ if (keyInit in accessibilityDirectMap || keyInit.startsWith('accessibility')) {
399
+ viewProps[keyInit] = valInit
400
+ continue
401
+ }
407
402
  } else {
408
- switch (keyInit) {
409
- case 'accessibilityRole': {
410
- if (valInit === 'none') {
411
- viewProps.role = 'presentation'
412
- } else {
413
- viewProps.role = accessibilityRoleToWebRole[valInit] || valInit
403
+ didUseKeyInit = true
404
+
405
+ if (keyInit in accessibilityDirectMap) {
406
+ viewProps[accessibilityDirectMap[keyInit]] = valInit
407
+ continue
408
+ } else {
409
+ switch (keyInit) {
410
+ case 'accessibilityRole': {
411
+ if (valInit === 'none') {
412
+ viewProps.role = 'presentation'
413
+ } else {
414
+ viewProps.role = accessibilityRoleToWebRole[valInit] || valInit
415
+ }
416
+ continue
414
417
  }
415
- continue
416
- }
417
- case 'accessibilityLabelledBy':
418
- case 'accessibilityFlowTo':
419
- case 'accessibilityControls':
420
- case 'accessibilityDescribedBy': {
421
- viewProps[`aria-${keyInit.replace('accessibility', '').toLowerCase()}`] =
422
- processIDRefList(valInit)
423
- continue
424
- }
425
- case 'accessibilityKeyShortcuts': {
426
- if (Array.isArray(valInit)) {
427
- viewProps['aria-keyshortcuts'] = valInit.join(' ')
418
+ case 'accessibilityLabelledBy':
419
+ case 'accessibilityFlowTo':
420
+ case 'accessibilityControls':
421
+ case 'accessibilityDescribedBy': {
422
+ viewProps[`aria-${keyInit.replace('accessibility', '').toLowerCase()}`] =
423
+ processIDRefList(valInit)
424
+ continue
428
425
  }
429
- continue
430
- }
431
- case 'accessibilityLiveRegion': {
432
- viewProps['aria-live'] = valInit === 'none' ? 'off' : valInit
433
- continue
434
- }
435
- case 'accessibilityReadOnly': {
436
- viewProps['aria-readonly'] = valInit
437
- // Enhance with native semantics
438
- if (
439
- elementType === 'input' ||
440
- elementType === 'select' ||
441
- elementType === 'textarea'
442
- ) {
443
- viewProps.readOnly = true
426
+ case 'accessibilityKeyShortcuts': {
427
+ if (Array.isArray(valInit)) {
428
+ viewProps['aria-keyshortcuts'] = valInit.join(' ')
429
+ }
430
+ continue
444
431
  }
445
- continue
446
- }
447
- case 'accessibilityRequired': {
448
- viewProps['aria-required'] = valInit
449
- // Enhance with native semantics
450
- if (
451
- elementType === 'input' ||
452
- elementType === 'select' ||
453
- elementType === 'textarea'
454
- ) {
455
- viewProps.required = valInit
432
+ case 'accessibilityLiveRegion': {
433
+ viewProps['aria-live'] = valInit === 'none' ? 'off' : valInit
434
+ continue
435
+ }
436
+ case 'accessibilityReadOnly': {
437
+ viewProps['aria-readonly'] = valInit
438
+ // Enhance with native semantics
439
+ if (
440
+ elementType === 'input' ||
441
+ elementType === 'select' ||
442
+ elementType === 'textarea'
443
+ ) {
444
+ viewProps.readOnly = true
445
+ }
446
+ continue
447
+ }
448
+ case 'accessibilityRequired': {
449
+ viewProps['aria-required'] = valInit
450
+ // Enhance with native semantics
451
+ if (
452
+ elementType === 'input' ||
453
+ elementType === 'select' ||
454
+ elementType === 'textarea'
455
+ ) {
456
+ viewProps.required = valInit
457
+ }
458
+ continue
459
+ }
460
+ default: {
461
+ didUseKeyInit = false
456
462
  }
457
- continue
458
- }
459
- default: {
460
- didUseKeyInit = false
461
463
  }
462
464
  }
463
465
  }
464
- }
465
-
466
- if (didUseKeyInit) {
467
- continue
468
- }
469
466
 
470
- if (valInit && valInit[0] === '_') {
471
- // if valid style key (or pseudo like color-hover):
472
- // this conditional and esp the pseudo check rarely runs so not a perf issue
473
- const isValidClassName = keyInit in validStyles
474
- const isMediaOrPseudo =
475
- !isValidClassName &&
476
- keyInit.includes(PROP_SPLIT) &&
477
- validStyles[keyInit.split(PROP_SPLIT)[0]]
467
+ if (didUseKeyInit) {
468
+ continue
469
+ }
478
470
 
479
- if (isValidClassName || isMediaOrPseudo) {
480
- if (process.env.NODE_ENV === 'development' && debug) {
481
- // biome-ignore lint/suspicious/noConsoleLog: ok
482
- console.log('tamagui classname prop', keyInit, valInit)
483
- }
471
+ if (valInit && valInit[0] === '_') {
472
+ // if valid style key (or pseudo like color-hover):
473
+ // this conditional and esp the pseudo check rarely runs so not a perf issue
474
+ const isValidClassName = keyInit in validStyles
475
+ const isMediaOrPseudo =
476
+ !isValidClassName &&
477
+ keyInit.includes(PROP_SPLIT) &&
478
+ validStyles[keyInit.split(PROP_SPLIT)[0]]
479
+
480
+ if (isValidClassName || isMediaOrPseudo) {
481
+ if (process.env.NODE_ENV === 'development' && debug) {
482
+ // biome-ignore lint/suspicious/noConsoleLog: ok
483
+ console.log('tamagui classname prop', keyInit, valInit)
484
+ }
484
485
 
485
- if (shouldDoClasses) {
486
- mergeClassName(transforms, classNames, keyInit, valInit, isMediaOrPseudo)
487
- delete style[keyInit]
488
- } else {
489
- style[keyInit] = reverseMapClassNameToValue(keyInit, valInit)
490
- delete className[keyInit]
486
+ if (shouldDoClasses) {
487
+ mergeClassName(transforms, classNames, keyInit, valInit, isMediaOrPseudo)
488
+ delete style[keyInit]
489
+ } else {
490
+ style[keyInit] = reverseMapClassNameToValue(keyInit, valInit)
491
+ delete className[keyInit]
492
+ }
493
+ continue
491
494
  }
492
- continue
493
495
  }
494
496
  }
495
497
  }
@@ -514,7 +516,10 @@ export const getSplitStyles: StyleSplitter = (
514
516
 
515
517
  const isStyleProp = isMediaOrPseudo || isVariant || isValidStyleKeyInit || isShorthand
516
518
 
517
- if (isStyleProp && props.asChild === 'except-style') {
519
+ if (
520
+ isStyleProp &&
521
+ (props.asChild === 'except-style' || props.asChild === 'except-style-web')
522
+ ) {
518
523
  continue
519
524
  }
520
525
 
@@ -545,7 +550,6 @@ export const getSplitStyles: StyleSplitter = (
545
550
  // biome-ignore lint/suspicious/noConsoleLog: <explanation>
546
551
  console.log({ isVariant, valInit, shouldPassProp })
547
552
  if (isClient) {
548
-
549
553
  // biome-ignore lint/suspicious/noConsoleLog: <explanation>
550
554
  console.log({
551
555
  variants,
@@ -554,7 +558,7 @@ export const getSplitStyles: StyleSplitter = (
554
558
  isHOCShouldPassThrough,
555
559
  curProps: { ...styleState.curProps },
556
560
  parentStaticConfig,
557
- });
561
+ })
558
562
  }
559
563
  console.groupEnd()
560
564
  }
@@ -629,7 +633,6 @@ export const getSplitStyles: StyleSplitter = (
629
633
  console.groupCollapsed(' 💠 expanded', keyInit, valInit)
630
634
  try {
631
635
  if (!isServer && isDevTools) {
632
-
633
636
  // biome-ignore lint/suspicious/noConsoleLog: <explanation>
634
637
  console.log({
635
638
  expanded,
@@ -642,7 +645,7 @@ export const getSplitStyles: StyleSplitter = (
642
645
  theme,
643
646
  usedKeys: { ...usedKeys },
644
647
  curProps: { ...styleState.curProps },
645
- });
648
+ })
646
649
  // biome-ignore lint/suspicious/noConsoleLog: ok
647
650
  console.log('expanded', expanded, '\nusedKeys', { ...usedKeys }, '\ncurrent', {
648
651
  ...style,
@@ -737,9 +740,9 @@ export const getSplitStyles: StyleSplitter = (
737
740
  if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
738
741
  // prettier-ignore
739
742
  console.groupCollapsed("pseudo (classes)", key);
740
-
743
+
741
744
  // biome-ignore lint/suspicious/noConsoleLog: <explanation>
742
- console.log({ pseudoStyleObject, pseudoStyles });
745
+ console.log({ pseudoStyleObject, pseudoStyles })
743
746
  console.groupEnd()
744
747
  }
745
748
 
@@ -777,7 +780,7 @@ export const getSplitStyles: StyleSplitter = (
777
780
  if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
778
781
  // prettier-ignore
779
782
  console.groupCollapsed("pseudo", key, { isDisabled });
780
-
783
+
781
784
  // biome-ignore lint/suspicious/noConsoleLog: <explanation>
782
785
  console.log(pseudoStyleObject, {
783
786
  isDisabled,
@@ -785,7 +788,7 @@ export const getSplitStyles: StyleSplitter = (
785
788
  descriptor,
786
789
  pseudoState,
787
790
  state: { ...componentState },
788
- });
791
+ })
789
792
  console.groupEnd()
790
793
  }
791
794
 
@@ -813,14 +816,13 @@ export const getSplitStyles: StyleSplitter = (
813
816
  }
814
817
 
815
818
  if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
816
-
817
819
  // biome-ignore lint/suspicious/noConsoleLog: <explanation>
818
- console.log(" subKey", pkey, shouldMerge, {
820
+ console.log(' subKey', pkey, shouldMerge, {
819
821
  importance,
820
822
  curImportance,
821
823
  pkey,
822
824
  val,
823
- });
825
+ })
824
826
  }
825
827
  }
826
828
  }
@@ -870,9 +872,15 @@ export const getSplitStyles: StyleSplitter = (
870
872
  const mediaKeyShort = key.slice(1)
871
873
 
872
874
  if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
873
-
874
875
  // biome-ignore lint/suspicious/noConsoleLog: ok
875
- console.log(` 📺 ${key}`, { key, val, mediaStyle, props, shouldDoClasses, componentState });
876
+ console.log(` 📺 ${key}`, {
877
+ key,
878
+ val,
879
+ mediaStyle,
880
+ props,
881
+ shouldDoClasses,
882
+ componentState,
883
+ })
876
884
  }
877
885
 
878
886
  // for some reason 'space' in val upsetting next ssr during prod build
@@ -1060,49 +1068,51 @@ export const getSplitStyles: StyleSplitter = (
1060
1068
  mergeStyleProp(styleState, props.style)
1061
1069
  }
1062
1070
 
1063
- fixStyles(style)
1071
+ if (!styleProps.noNormalize) {
1072
+ fixStyles(style)
1064
1073
 
1065
- // shouldnt this be better? but breaks some tests wierdly, need to check
1066
- // if (isWeb && !staticConfig.isReactNative) {
1067
- if (isWeb && !staticConfig.isReactNative) {
1068
- styleToCSS(style)
1069
- }
1074
+ // shouldnt this be better? but breaks some tests wierdly, need to check
1075
+ // if (isWeb && !staticConfig.isReactNative) {
1076
+ if (isWeb && !staticConfig.isReactNative) {
1077
+ styleToCSS(style)
1078
+ }
1070
1079
 
1071
- // these are only the flat transforms
1072
- // always do this at the very end to preserve the order strictly (animations, origin)
1073
- // and allow proper merging of all pseudos before applying
1074
- if (styleState.transforms) {
1075
- // we need to match the order for animations to work because it needs consistent order
1076
- // was thinking of having something like `state.prevTransformsOrder = ['y', 'x', ...]
1077
- // but if we just handle it here its not a big cost and avoids having stateful things
1078
- // so the strategy is: always sort by a consistent order, until you run into a "duplicate"
1079
- // because you can have something like:
1080
- // [{ translateX: 0 }, { scale: 1 }, { translateX: 10 }]
1081
- // so basically we sort until we get to a duplicate... we could sort even smarter but
1082
- // this should work for most (all?) of our cases since the order preservation really only needs to apply
1083
- // to the "flat" transform props
1084
- Object.entries(styleState.transforms)
1085
- .sort(([a], [b]) => a.localeCompare(b))
1086
- .forEach(([key, val]) => {
1087
- mergeTransform(style, key, val, true)
1088
- })
1089
- }
1080
+ // these are only the flat transforms
1081
+ // always do this at the very end to preserve the order strictly (animations, origin)
1082
+ // and allow proper merging of all pseudos before applying
1083
+ if (styleState.transforms) {
1084
+ // we need to match the order for animations to work because it needs consistent order
1085
+ // was thinking of having something like `state.prevTransformsOrder = ['y', 'x', ...]
1086
+ // but if we just handle it here its not a big cost and avoids having stateful things
1087
+ // so the strategy is: always sort by a consistent order, until you run into a "duplicate"
1088
+ // because you can have something like:
1089
+ // [{ translateX: 0 }, { scale: 1 }, { translateX: 10 }]
1090
+ // so basically we sort until we get to a duplicate... we could sort even smarter but
1091
+ // this should work for most (all?) of our cases since the order preservation really only needs to apply
1092
+ // to the "flat" transform props
1093
+ Object.entries(styleState.transforms)
1094
+ .sort(([a], [b]) => a.localeCompare(b))
1095
+ .forEach(([key, val]) => {
1096
+ mergeTransform(style, key, val, true)
1097
+ })
1098
+ }
1090
1099
 
1091
- // add in defaults if not set:
1092
- if (parentSplitStyles) {
1093
- if (process.env.TAMAGUI_TARGET === 'web') {
1094
- if (shouldDoClasses) {
1095
- for (const key in parentSplitStyles.classNames) {
1096
- const val = parentSplitStyles.classNames[key]
1097
- if (key in style || key in classNames) continue
1098
- classNames[key] = val
1100
+ // add in defaults if not set:
1101
+ if (parentSplitStyles) {
1102
+ if (process.env.TAMAGUI_TARGET === 'web') {
1103
+ if (shouldDoClasses) {
1104
+ for (const key in parentSplitStyles.classNames) {
1105
+ const val = parentSplitStyles.classNames[key]
1106
+ if (key in style || key in classNames) continue
1107
+ classNames[key] = val
1108
+ }
1099
1109
  }
1100
1110
  }
1101
- }
1102
- if (!shouldDoClasses) {
1103
- for (const key in parentSplitStyles.style) {
1104
- if (key in classNames || key in style) continue
1105
- style[key] = parentSplitStyles.style[key]
1111
+ if (!shouldDoClasses) {
1112
+ for (const key in parentSplitStyles.style) {
1113
+ if (key in classNames || key in style) continue
1114
+ style[key] = parentSplitStyles.style[key]
1115
+ }
1106
1116
  }
1107
1117
  }
1108
1118
  }
@@ -1155,27 +1165,27 @@ export const getSplitStyles: StyleSplitter = (
1155
1165
  style = retainedStyles || {}
1156
1166
  }
1157
1167
  }
1158
- }
1159
1168
 
1160
- if (transforms) {
1161
- for (const namespace in transforms) {
1162
- if (!transforms[namespace]) {
1163
- if (process.env.NODE_ENV === 'development') {
1164
- console.warn('Error no transform', transforms, namespace)
1169
+ if (transforms) {
1170
+ for (const namespace in transforms) {
1171
+ if (!transforms[namespace]) {
1172
+ if (process.env.NODE_ENV === 'development') {
1173
+ console.warn('Error no transform', transforms, namespace)
1174
+ }
1175
+ continue
1165
1176
  }
1166
- continue
1167
- }
1168
- const [hash, val] = transforms[namespace]
1169
- const identifier = `_transform${hash}`
1170
- if (isClient && !insertedTransforms[identifier]) {
1171
- const rule = `.${identifier} { transform: ${val}; }`
1172
- addStyleToInsertRules(rulesToInsert, {
1173
- identifier,
1174
- rules: [rule],
1175
- property: namespace,
1176
- } as StyleObject)
1177
+ const [hash, val] = transforms[namespace]
1178
+ const identifier = `_transform${hash}`
1179
+ if (isClient && !insertedTransforms[identifier]) {
1180
+ const rule = `.${identifier} { transform: ${val}; }`
1181
+ addStyleToInsertRules(rulesToInsert, {
1182
+ identifier,
1183
+ rules: [rule],
1184
+ property: namespace,
1185
+ } as StyleObject)
1186
+ }
1187
+ classNames[namespace] = identifier
1177
1188
  }
1178
- classNames[namespace] = identifier
1179
1189
  }
1180
1190
  }
1181
1191
 
@@ -1328,7 +1338,7 @@ function mergeClassName(
1328
1338
  }
1329
1339
 
1330
1340
  function mergeStyle(styleState: GetStyleState, key: string, val: any) {
1331
- const { classNames, viewProps, style, usedKeys } = styleState
1341
+ const { classNames, viewProps, style, usedKeys, styleProps } = styleState
1332
1342
  if (isWeb && val?.[0] === '_') {
1333
1343
  classNames[key] = val
1334
1344
  usedKeys[key] ||= 1
@@ -1336,7 +1346,8 @@ function mergeStyle(styleState: GetStyleState, key: string, val: any) {
1336
1346
  styleState.transforms ||= {}
1337
1347
  styleState.transforms[key] = val
1338
1348
  } else {
1339
- const out = isWeb ? normalizeValueWithProperty(val, key) : val
1349
+ const out =
1350
+ isWeb && !styleProps.noNormalize ? normalizeValueWithProperty(val, key) : val
1340
1351
  if (key in validStylesOnBaseProps) {
1341
1352
  viewProps[key] = out
1342
1353
  } else {
@@ -1351,7 +1362,7 @@ export const getSubStyle = (
1351
1362
  styleIn: Object,
1352
1363
  avoidMergeTransform?: boolean
1353
1364
  ): TextStyleProps => {
1354
- const { staticConfig, props, conf } = styleState
1365
+ const { staticConfig, props, conf, styleProps } = styleState
1355
1366
  const styleOut: TextStyleProps = {}
1356
1367
 
1357
1368
  for (let key in styleIn) {
@@ -1365,12 +1376,16 @@ export const getSubStyle = (
1365
1376
  if (!avoidMergeTransform && skey in stylePropsTransform) {
1366
1377
  mergeTransform(styleOut, skey, sval)
1367
1378
  } else {
1368
- styleOut[skey] = normalizeValueWithProperty(sval, key)
1379
+ styleOut[skey] = styleProps.noNormalize
1380
+ ? sval
1381
+ : normalizeValueWithProperty(sval, key)
1369
1382
  }
1370
1383
  }
1371
1384
  }
1372
1385
 
1373
- fixStyles(styleOut)
1386
+ if (!styleProps.noNormalize) {
1387
+ fixStyles(styleOut)
1388
+ }
1374
1389
 
1375
1390
  return styleOut
1376
1391
  }