@hanzogui/kitchen-sink 3.0.5

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 (431) hide show
  1. package/.detoxrc.js +130 -0
  2. package/.env.production +2 -0
  3. package/.maestro/config.yaml +4 -0
  4. package/.maestro/flows/shorthand-variables.yaml +23 -0
  5. package/.watchmanconfig +1 -0
  6. package/LICENSE +21 -0
  7. package/README.md +11 -0
  8. package/app.json +43 -0
  9. package/assets/adaptive-icon.png +0 -0
  10. package/assets/favicon.png +0 -0
  11. package/assets/icon.png +0 -0
  12. package/assets/splash.png +0 -0
  13. package/babel.config.js +25 -0
  14. package/e2e/CompilerExtraction.test.ts +147 -0
  15. package/e2e/GroupPressNative.test.ts +167 -0
  16. package/e2e/MediaQueryGtMd.test.ts +71 -0
  17. package/e2e/NativePortal.test.ts +113 -0
  18. package/e2e/PointerEvents.test.ts +116 -0
  19. package/e2e/PressStyleNative.noRngh.test.ts +191 -0
  20. package/e2e/PressStyleNative.test.ts +231 -0
  21. package/e2e/SafeArea.test.ts +57 -0
  22. package/e2e/SelectAndroidOnPress.test.ts +181 -0
  23. package/e2e/SelectRemount.test.ts +137 -0
  24. package/e2e/SheetDragResist.test.ts +370 -0
  25. package/e2e/SheetKeyboardDrag.test.ts +249 -0
  26. package/e2e/SheetScrollableDrag.test.ts +560 -0
  27. package/e2e/ShorthandVariables.test.ts +53 -0
  28. package/e2e/ThemeChangeBasic.test.ts +123 -0
  29. package/e2e/ThemeMutation.test.ts +80 -0
  30. package/e2e/check-rngh-status.test.ts +31 -0
  31. package/e2e/jest.config.js +19 -0
  32. package/e2e/utils/colors.ts +75 -0
  33. package/e2e/utils/navigation.ts +53 -0
  34. package/eas.json +22 -0
  35. package/flows/AlertDialog.yaml +17 -0
  36. package/flows/OpenApp.yaml +25 -0
  37. package/flows/Select.yaml +13 -0
  38. package/flows/Sheet.yaml +12 -0
  39. package/flows/Tabs.yaml +13 -0
  40. package/flows/Toast.yaml +14 -0
  41. package/flows/WarmUp.yaml +24 -0
  42. package/index.html +21 -0
  43. package/index.js +17 -0
  44. package/metro.config.js +64 -0
  45. package/next-router-shim.ts +9 -0
  46. package/package.json +118 -0
  47. package/plans/toast-2.md +471 -0
  48. package/playwright.config.ts +71 -0
  49. package/plugins/expo-modules-core-swift6.js +76 -0
  50. package/pod-install.sh +7 -0
  51. package/public/favicon.svg +70 -0
  52. package/public/fonts/inter.css +15 -0
  53. package/public/fonts/noto-cn.otf +0 -0
  54. package/public/gui-icon.svg +68 -0
  55. package/run-detox.sh +230 -0
  56. package/run-native-tests.sh +4 -0
  57. package/run-tests-parallel.ts +195 -0
  58. package/screenshots/Screenshotter.test.tsx +48 -0
  59. package/src/AnimationDemos.tsx +131 -0
  60. package/src/App.native.tsx +121 -0
  61. package/src/App.tsx +121 -0
  62. package/src/Navigation.tsx +98 -0
  63. package/src/Sandbox.tsx +87 -0
  64. package/src/TestDynamicEval.tsx +33 -0
  65. package/src/TestNativeSheet.tsx +100 -0
  66. package/src/components/TimedRender.tsx +18 -0
  67. package/src/constants/test-ids.ts +52 -0
  68. package/src/features/demos/demo-screen.tsx +72 -0
  69. package/src/features/home/ColorSchemeListItem.tsx +41 -0
  70. package/src/features/home/TestBuildAButton.tsx +102 -0
  71. package/src/features/home/TestSeparator.tsx +0 -0
  72. package/src/features/home/screen.tsx +285 -0
  73. package/src/features/testcases/screen.tsx +59 -0
  74. package/src/features/testcases/test-screen.tsx +50 -0
  75. package/src/generatedV5Theme.ts +112 -0
  76. package/src/gui.config.ts +411 -0
  77. package/src/guy.png +0 -0
  78. package/src/index.tsx +6 -0
  79. package/src/provider/index.tsx +18 -0
  80. package/src/test-gui-stack.tsx +11 -0
  81. package/src/test.tsx +3 -0
  82. package/src/useKitchenSinkTheme.tsx +15 -0
  83. package/src/usecases/ActionsSheetComparison.tsx +194 -0
  84. package/src/usecases/AnimatePresenceEnterExitCase.tsx +255 -0
  85. package/src/usecases/AnimatePresenceExitTest.tsx +69 -0
  86. package/src/usecases/AnimatedByProp.tsx +39 -0
  87. package/src/usecases/AnimationComprehensiveCase.tsx +2515 -0
  88. package/src/usecases/AnimationValueLoggingCase.tsx +526 -0
  89. package/src/usecases/AnimationsWithMediaQueriesCase.tsx +110 -0
  90. package/src/usecases/Benchmark.tsx +148 -0
  91. package/src/usecases/BenchmarkSelect.tsx +34 -0
  92. package/src/usecases/ButtonCircular.tsx +3 -0
  93. package/src/usecases/ButtonCustom.tsx +33 -0
  94. package/src/usecases/ButtonIconColor.tsx +18 -0
  95. package/src/usecases/ButtonInverse.tsx +30 -0
  96. package/src/usecases/ButtonUnstyled.tsx +31 -0
  97. package/src/usecases/CheckboxDisabledOnPress.tsx +62 -0
  98. package/src/usecases/ClickDuringEnterCase.tsx +59 -0
  99. package/src/usecases/CodeExamplesInput.tsx +9 -0
  100. package/src/usecases/ColorTokenFallback.tsx +52 -0
  101. package/src/usecases/CompilerExtraction.tsx +380 -0
  102. package/src/usecases/ComplexVariants.tsx +164 -0
  103. package/src/usecases/CrashAdaptSheet.tsx +98 -0
  104. package/src/usecases/CustomStyledAnimatedPopover.tsx +42 -0
  105. package/src/usecases/CustomStyledAnimatedTooltip.tsx +72 -0
  106. package/src/usecases/DOMNodeAPIs.tsx +154 -0
  107. package/src/usecases/DialogFocusScopeCase.tsx +277 -0
  108. package/src/usecases/DialogFocusScopeDebug.tsx +85 -0
  109. package/src/usecases/DialogNestedCase.tsx +121 -0
  110. package/src/usecases/DialogOpenControlled.tsx +49 -0
  111. package/src/usecases/DialogPointerEventsCase.tsx +58 -0
  112. package/src/usecases/DialogScopedCase.tsx +106 -0
  113. package/src/usecases/DialogSheetAdaptCase.tsx +178 -0
  114. package/src/usecases/DialogSheetAdaptResizeCase.tsx +98 -0
  115. package/src/usecases/DismissLayerStackingCase.tsx +223 -0
  116. package/src/usecases/DriverDisableAnimationPropsCase.tsx +44 -0
  117. package/src/usecases/Example.tsx +10 -0
  118. package/src/usecases/ExitCompletionCase.tsx +713 -0
  119. package/src/usecases/FocusVisibleButton.tsx +14 -0
  120. package/src/usecases/FocusVisibleButtonPointer.tsx +13 -0
  121. package/src/usecases/FocusVisibleButtonWithFocusStyle.tsx +16 -0
  122. package/src/usecases/FocusWithinCase.tsx +55 -0
  123. package/src/usecases/FontTokensInVariants.tsx +14 -0
  124. package/src/usecases/FormButtonTypeCase.tsx +34 -0
  125. package/src/usecases/GlobalScopedTriggerIsolationCase.tsx +178 -0
  126. package/src/usecases/GroupHoverMobile.tsx +39 -0
  127. package/src/usecases/GroupPressInVariant.tsx +92 -0
  128. package/src/usecases/GroupPressNative.tsx +200 -0
  129. package/src/usecases/GroupProp.tsx +96 -0
  130. package/src/usecases/GroupPseudoVariantOverride.tsx +56 -0
  131. package/src/usecases/GroupUseCases.tsx +94 -0
  132. package/src/usecases/HeightMediaQueryOverrideCase.tsx +183 -0
  133. package/src/usecases/InputAutoFocusAfterMenuCase.tsx +105 -0
  134. package/src/usecases/InputAutoFocusStyledCase.tsx +39 -0
  135. package/src/usecases/KeyboardControllerTest.tsx +146 -0
  136. package/src/usecases/ListItem.tsx +123 -0
  137. package/src/usecases/MediaQueriesV5.tsx +137 -0
  138. package/src/usecases/MediaQueryGtMd.tsx +73 -0
  139. package/src/usecases/MenuAboveDialogCase.tsx +75 -0
  140. package/src/usecases/MenuAccessibilityCase.tsx +133 -0
  141. package/src/usecases/MenuAnimatePositionCase.tsx +41 -0
  142. package/src/usecases/MenuArrowAnimatePresenceCase.tsx +98 -0
  143. package/src/usecases/MenuAsChildPositionCase.tsx +24 -0
  144. package/src/usecases/MenuAutoResizeCase.tsx +57 -0
  145. package/src/usecases/MenuBottomCase.tsx +55 -0
  146. package/src/usecases/MenuFocusLeaveCase.tsx +135 -0
  147. package/src/usecases/MenuHighlightCase.tsx +44 -0
  148. package/src/usecases/MenuItemFocusCase.tsx +79 -0
  149. package/src/usecases/MenuItemPseudoOverrideCase.tsx +270 -0
  150. package/src/usecases/MenuMultiTriggerCase.tsx +47 -0
  151. package/src/usecases/MenuOverflowCase.tsx +60 -0
  152. package/src/usecases/MenuSubCase.tsx +223 -0
  153. package/src/usecases/MenuSubLeftCase.tsx +178 -0
  154. package/src/usecases/MenuSubNestedPositionCase.tsx +171 -0
  155. package/src/usecases/MenuSubStyledCase.tsx +145 -0
  156. package/src/usecases/MenuThemeCase.tsx +50 -0
  157. package/src/usecases/MenuUnstyledCase.tsx +52 -0
  158. package/src/usecases/MultiDriverAnimation.tsx +118 -0
  159. package/src/usecases/NativePortalTest.tsx +179 -0
  160. package/src/usecases/NewInputBasic.tsx +16 -0
  161. package/src/usecases/NewInputEvents.tsx +29 -0
  162. package/src/usecases/NonGuiTextStyledType.tsx +23 -0
  163. package/src/usecases/OnLayoutCase.tsx +134 -0
  164. package/src/usecases/OnLayoutScaleCase.tsx +88 -0
  165. package/src/usecases/OnLayoutStressCase.tsx +353 -0
  166. package/src/usecases/OpacityModifierCase.tsx +113 -0
  167. package/src/usecases/OverlayStyled.tsx +66 -0
  168. package/src/usecases/ParagraphSpanFontInheritance.tsx +53 -0
  169. package/src/usecases/PlaceholderTextColor.tsx +20 -0
  170. package/src/usecases/PointerEventsCase.tsx +100 -0
  171. package/src/usecases/PopoverAndMenuMultiTriggerCase.tsx +138 -0
  172. package/src/usecases/PopoverCase.tsx +222 -0
  173. package/src/usecases/PopoverContentStyledPlusAnimations.tsx +44 -0
  174. package/src/usecases/PopoverFocusScopeCase.tsx +171 -0
  175. package/src/usecases/PopoverHoverableCase.tsx +167 -0
  176. package/src/usecases/PopoverHoverableDisableClickCase.tsx +118 -0
  177. package/src/usecases/PopoverHoverableRapidCase.tsx +103 -0
  178. package/src/usecases/PopoverHoverableScopedCase.tsx +135 -0
  179. package/src/usecases/PopoverScopedCase.tsx +76 -0
  180. package/src/usecases/PopoverTriggerIsolationCase.tsx +80 -0
  181. package/src/usecases/PressStyleNative.tsx +143 -0
  182. package/src/usecases/PseudoStyleMerge.tsx +25 -0
  183. package/src/usecases/PseudoTransitionCase.tsx +174 -0
  184. package/src/usecases/RawAnimatedValueCase.tsx +231 -0
  185. package/src/usecases/RemoveScrollCase.tsx +66 -0
  186. package/src/usecases/RenderPropCase.tsx +263 -0
  187. package/src/usecases/SafeAreaCase.tsx +236 -0
  188. package/src/usecases/ScrollViewRefCase.tsx +88 -0
  189. package/src/usecases/SecondPage.tsx +5 -0
  190. package/src/usecases/SelectAndroidOnPress.tsx +129 -0
  191. package/src/usecases/SelectFocusScopeCase.tsx +270 -0
  192. package/src/usecases/SelectRemount.tsx +136 -0
  193. package/src/usecases/Shadows.tsx +5 -0
  194. package/src/usecases/SheetAnimationCase.tsx +155 -0
  195. package/src/usecases/SheetDragCase.tsx +183 -0
  196. package/src/usecases/SheetDragResistCase.tsx +433 -0
  197. package/src/usecases/SheetDragResistCase.web.tsx +359 -0
  198. package/src/usecases/SheetKeyboardDragCase.tsx +328 -0
  199. package/src/usecases/SheetKeyboardFitContentCase.tsx +165 -0
  200. package/src/usecases/SheetOnAnimationCompleteCase.tsx +54 -0
  201. package/src/usecases/SheetScrollLockCase.tsx +166 -0
  202. package/src/usecases/SheetScrollableDrag.tsx +249 -0
  203. package/src/usecases/SheetSnapPointsFitCase.tsx +393 -0
  204. package/src/usecases/ShorthandVariables.tsx +49 -0
  205. package/src/usecases/SlowThemeReRender.tsx +48 -0
  206. package/src/usecases/SpinnerCustomColors.tsx +34 -0
  207. package/src/usecases/StackZIndex.tsx +82 -0
  208. package/src/usecases/StressPage.tsx +301 -0
  209. package/src/usecases/StylePlatform.tsx +30 -0
  210. package/src/usecases/StyleProp.tsx +29 -0
  211. package/src/usecases/StyledAnchor.tsx +27 -0
  212. package/src/usecases/StyledButtonAnimationAuto.tsx +99 -0
  213. package/src/usecases/StyledButtonTheme.tsx +63 -0
  214. package/src/usecases/StyledButtonVariantPseudo.tsx +25 -0
  215. package/src/usecases/StyledButtonVariantPseudoMerge.tsx +77 -0
  216. package/src/usecases/StyledCheckboxTheme.tsx +23 -0
  217. package/src/usecases/StyledContextColor.tsx +246 -0
  218. package/src/usecases/StyledContextTokens.tsx +147 -0
  219. package/src/usecases/StyledHOCNamed.tsx +20 -0
  220. package/src/usecases/StyledHtmlCase.tsx +144 -0
  221. package/src/usecases/StyledIconColor.tsx +19 -0
  222. package/src/usecases/StyledInputFocusStyle.tsx +21 -0
  223. package/src/usecases/StyledInputOnFocus.tsx +30 -0
  224. package/src/usecases/StyledMediaQueryMerge.tsx +95 -0
  225. package/src/usecases/StyledOverridePsuedo.tsx +26 -0
  226. package/src/usecases/StyledRNW.tsx +61 -0
  227. package/src/usecases/StyledStyleableInputOnFocus.tsx +34 -0
  228. package/src/usecases/StyledStyleableInputVariant.tsx +48 -0
  229. package/src/usecases/StyledStyledStyleableInputOnFocus.tsx +36 -0
  230. package/src/usecases/StyledVariantTextColor.tsx +25 -0
  231. package/src/usecases/StyledViewOnFocus.tsx +32 -0
  232. package/src/usecases/TabHoverAnimationCase.tsx +212 -0
  233. package/src/usecases/TextNestedInheritance.tsx +80 -0
  234. package/src/usecases/ThemeChange.tsx +100 -0
  235. package/src/usecases/ThemeChangeBasic.tsx +52 -0
  236. package/src/usecases/ThemeComponentResolution.tsx +119 -0
  237. package/src/usecases/ThemeConditionalName.tsx +31 -0
  238. package/src/usecases/ThemeMediaAnimationCase.tsx +39 -0
  239. package/src/usecases/ThemeMutation.tsx +86 -0
  240. package/src/usecases/ThemeNested.tsx +103 -0
  241. package/src/usecases/ThemeReset.tsx +62 -0
  242. package/src/usecases/ThemeShallowCase.tsx +83 -0
  243. package/src/usecases/ToastCase.tsx +46 -0
  244. package/src/usecases/ToggleGroupActiveProps.tsx +40 -0
  245. package/src/usecases/ToggleGroupXGroupCase.tsx +104 -0
  246. package/src/usecases/TooltipAnimationCase.tsx +99 -0
  247. package/src/usecases/TooltipCase.tsx +32 -0
  248. package/src/usecases/TooltipGlobalPatternCase.tsx +83 -0
  249. package/src/usecases/TooltipGroupCase.tsx +102 -0
  250. package/src/usecases/TooltipMultiTriggerCase.tsx +88 -0
  251. package/src/usecases/TooltipPositionJumpCase.tsx +91 -0
  252. package/src/usecases/TooltipTriggerInlineCase.tsx +60 -0
  253. package/src/usecases/TransformMediaQueryMerge.tsx +98 -0
  254. package/src/usecases/UseCases.tsx +409 -0
  255. package/src/usecases/UseTheme.tsx +41 -0
  256. package/src/usecases/V5ThemeBuilderOutput.tsx +231 -0
  257. package/src/usecases/VariantFontFamily.tsx +25 -0
  258. package/src/usecases/VariantsOrder.tsx +117 -0
  259. package/src/usecases/ZIndex.tsx +155 -0
  260. package/src/usecases/helpers.tsx +44 -0
  261. package/src/usecases/index.native.ts +122 -0
  262. package/src/usecases/index.ts +3 -0
  263. package/src/usecases/index.web.ts +177 -0
  264. package/tests/AnimatePresenceEnterExit.animated.test.tsx +176 -0
  265. package/tests/AnimatedByProp.animated.test.tsx +138 -0
  266. package/tests/AnimationBehavior.animated.test.tsx +543 -0
  267. package/tests/AnimationTiming.animated.test.tsx +195 -0
  268. package/tests/AnimationsWithMediaQueries.animated.test.tsx +154 -0
  269. package/tests/BuildAButton.test.tsx +87 -0
  270. package/tests/ButtonCircular.test.tsx +17 -0
  271. package/tests/ButtonCustom.test.tsx +17 -0
  272. package/tests/ButtonIconColor.test.tsx +23 -0
  273. package/tests/ButtonUnstyled.test.tsx +56 -0
  274. package/tests/ClickDuringEnter.animated.test.tsx +174 -0
  275. package/tests/ColorTokenFallback.test.tsx +45 -0
  276. package/tests/DOMNodeAPIs.test.tsx +161 -0
  277. package/tests/DialogFocusScope.animated.test.tsx +309 -0
  278. package/tests/DialogNested.test.tsx +128 -0
  279. package/tests/DialogOpenControlled.test.tsx +42 -0
  280. package/tests/DialogPointerEvents.animated.test.tsx +108 -0
  281. package/tests/DialogScoped.test.tsx +137 -0
  282. package/tests/DialogSheetAdapt.test.tsx +68 -0
  283. package/tests/DialogSheetAdaptResize.test.tsx +161 -0
  284. package/tests/DismissLayerStacking.test.tsx +292 -0
  285. package/tests/DriverDisableAnimationProps.animated.test.tsx +157 -0
  286. package/tests/ExitCompletion.animated.test.tsx +425 -0
  287. package/tests/ExitTimingCheck.animated.test.ts +34 -0
  288. package/tests/FocusVisibleButton.test.tsx +41 -0
  289. package/tests/FocusVisibleButtonPointerFocus.test.tsx +23 -0
  290. package/tests/FocusVisibleButtonPointerFocusWithFocusStyle.test.tsx +40 -0
  291. package/tests/FocusWithinStyle.animated.test.tsx +66 -0
  292. package/tests/FocusWithinStyle.test.tsx +60 -0
  293. package/tests/FormButtonType.test.tsx +42 -0
  294. package/tests/GlobalScopedTriggerIsolation.test.tsx +89 -0
  295. package/tests/GroupHoverMobile.test.tsx +52 -0
  296. package/tests/GroupPressInVariant.test.tsx +82 -0
  297. package/tests/GroupProp.test.tsx +30 -0
  298. package/tests/GroupPseudoVariantOverride.test.tsx +57 -0
  299. package/tests/GroupUseCases.test.tsx +111 -0
  300. package/tests/GuiSiteMotion.test.ts +481 -0
  301. package/tests/HeightMediaQueryOverride.test.tsx +112 -0
  302. package/tests/InputAutoFocusAfterMenu.test.tsx +55 -0
  303. package/tests/InputAutoFocusStyled.test.tsx +22 -0
  304. package/tests/ListItem.test.tsx +129 -0
  305. package/tests/MediaQueriesV5.test.tsx +113 -0
  306. package/tests/MediaQueryGtMd.test.tsx +84 -0
  307. package/tests/MenuAboveDialog.test.tsx +108 -0
  308. package/tests/MenuAccessibility.test.tsx +346 -0
  309. package/tests/MenuAnimatePosition.animated.test.tsx +57 -0
  310. package/tests/MenuArrowAnimatePresence.animated.test.tsx +71 -0
  311. package/tests/MenuAsChildPosition.test.tsx +16 -0
  312. package/tests/MenuAutoResize.test.tsx +54 -0
  313. package/tests/MenuFocusLeave.test.tsx +181 -0
  314. package/tests/MenuHighlight.test.tsx +165 -0
  315. package/tests/MenuHoverKeyboardBugs.test.tsx +252 -0
  316. package/tests/MenuItemFocus.test.tsx +59 -0
  317. package/tests/MenuItemPseudoOverride.test.tsx +231 -0
  318. package/tests/MenuMultiTrigger.test.tsx +101 -0
  319. package/tests/MenuOverflow.test.tsx +93 -0
  320. package/tests/MenuStayInFrame.test.tsx +102 -0
  321. package/tests/MenuSubKeyboardFocus.test.tsx +220 -0
  322. package/tests/MenuSubLeftSafePolygon.test.tsx +88 -0
  323. package/tests/MenuSubNestedPosition.test.tsx +48 -0
  324. package/tests/MenuSubSafePolygon.test.tsx +97 -0
  325. package/tests/MenuSubStyled.test.tsx +40 -0
  326. package/tests/MenuTheme.test.tsx +34 -0
  327. package/tests/MenuUnstyled.test.tsx +56 -0
  328. package/tests/MultiDriverAnimation.test.tsx +207 -0
  329. package/tests/NewInputBasic.test.tsx +50 -0
  330. package/tests/NewInputEvents.test.tsx +55 -0
  331. package/tests/OnLayout.test.tsx +163 -0
  332. package/tests/OnLayoutScale.test.tsx +100 -0
  333. package/tests/OnLayoutStress.test.tsx +304 -0
  334. package/tests/ParagraphSpanFontInheritance.test.tsx +73 -0
  335. package/tests/PointerEvents.test.tsx +123 -0
  336. package/tests/Popover.animated.test.tsx +234 -0
  337. package/tests/PopoverAndMenuMultiTrigger.test.tsx +184 -0
  338. package/tests/PopoverAnimatePosition.animated.test.tsx +51 -0
  339. package/tests/PopoverClickDuringEnter.animated.test.tsx +197 -0
  340. package/tests/PopoverFocusScope.test.tsx +242 -0
  341. package/tests/PopoverHoverable.test.tsx +383 -0
  342. package/tests/PopoverHoverableDisableClick.test.tsx +106 -0
  343. package/tests/PopoverHoverableRapid.test.tsx +129 -0
  344. package/tests/PopoverHoverableReposition.test.tsx +111 -0
  345. package/tests/PopoverHoverableScoped.animated.test.tsx +103 -0
  346. package/tests/PopoverHoverableStress.test.tsx +169 -0
  347. package/tests/PopoverInitialPosition.animated.test.tsx +82 -0
  348. package/tests/PopoverMiddlewareSkipRegression.animated.test.tsx +221 -0
  349. package/tests/PopoverScoped.test.tsx +128 -0
  350. package/tests/PopoverScopedPositionGlitch.animated.test.tsx +184 -0
  351. package/tests/PopoverTriggerIsolation.test.tsx +62 -0
  352. package/tests/PseudoTransition.animated.test.tsx +319 -0
  353. package/tests/RawAnimatedValue.test.tsx +147 -0
  354. package/tests/RemoveScroll.test.tsx +223 -0
  355. package/tests/RenderProp.test.tsx +293 -0
  356. package/tests/ScrollViewRef.test.tsx +39 -0
  357. package/tests/SelectClickHold.test.tsx +147 -0
  358. package/tests/SelectFocusScope.test.tsx +176 -0
  359. package/tests/SelectInnerPositioning.test.tsx +82 -0
  360. package/tests/SelectKeyboardNav.test.tsx +173 -0
  361. package/tests/SelectPositioning.test.tsx +56 -0
  362. package/tests/SelectTypeahead.test.tsx +63 -0
  363. package/tests/Shadows.test.tsx +14 -0
  364. package/tests/SheetAnimation.animated.test.tsx +413 -0
  365. package/tests/SheetDrag.animated.test.tsx +223 -0
  366. package/tests/SheetDragResist.animated.test.tsx +393 -0
  367. package/tests/SheetOnAnimationComplete.animated.test.tsx +62 -0
  368. package/tests/SheetScrollLock.animated.test.tsx +287 -0
  369. package/tests/SheetScrollableDrag.animated.test.tsx +1264 -0
  370. package/tests/SheetSnapPointsFit.animated.test.tsx +259 -0
  371. package/tests/ShorthandVariables.test.tsx +44 -0
  372. package/tests/SpinnerCustomColors.test.tsx +67 -0
  373. package/tests/StackZIndex.test.tsx +51 -0
  374. package/tests/StressPagePerf.test.tsx +76 -0
  375. package/tests/StylePlatform.test.tsx +38 -0
  376. package/tests/StyleProp.test.tsx +20 -0
  377. package/tests/StyledAnchor.test.tsx +17 -0
  378. package/tests/StyledButtonTheme.test.tsx +22 -0
  379. package/tests/StyledButtonVariantPseudo.test.tsx +20 -0
  380. package/tests/StyledButtonVariantPseudoMerge.animated.test.tsx +33 -0
  381. package/tests/StyledCheckboxTheme.test.tsx +16 -0
  382. package/tests/StyledContextColor.test.tsx +119 -0
  383. package/tests/StyledContextTokens.test.tsx +56 -0
  384. package/tests/StyledHOCNamed.test.tsx +16 -0
  385. package/tests/StyledHtml.test.tsx +161 -0
  386. package/tests/StyledIconColor.test.tsx +32 -0
  387. package/tests/StyledInputFocusStyle.test.tsx +19 -0
  388. package/tests/StyledInputOnFocus.test.tsx +27 -0
  389. package/tests/StyledMediaQueryMerge.test.tsx +66 -0
  390. package/tests/StyledRNW.test.tsx +17 -0
  391. package/tests/StyledStyleableInputOnFocus.test.tsx +27 -0
  392. package/tests/StyledStyleableInputVariant.test.tsx +22 -0
  393. package/tests/StyledStyledStyleableInputOnFocus.test.tsx +27 -0
  394. package/tests/StyledVariantTextColor.test.tsx +24 -0
  395. package/tests/StyledViewOnFocus.test.tsx +27 -0
  396. package/tests/TabHoverAnimation.animated.test.tsx +468 -0
  397. package/tests/TabHoverPositionSmooth.animated.test.tsx +129 -0
  398. package/tests/TextNestedInheritance.test.tsx +93 -0
  399. package/tests/ThemeChange.test.tsx +70 -0
  400. package/tests/ThemeComponentResolution.test.tsx +82 -0
  401. package/tests/ThemeConditionalName.test.tsx +34 -0
  402. package/tests/ThemeMediaAnimation.test.tsx +65 -0
  403. package/tests/ThemeNested.test.tsx +141 -0
  404. package/tests/ThemeReset.test.tsx +63 -0
  405. package/tests/ThemeShallow.test.tsx +95 -0
  406. package/tests/Toast.test.tsx +106 -0
  407. package/tests/ToggleGroup.test.tsx +61 -0
  408. package/tests/ToggleGroupActiveProps.test.tsx +38 -0
  409. package/tests/ToggleGroupXGroup.test.tsx +172 -0
  410. package/tests/TooltipAnimation.animated.test.tsx +260 -0
  411. package/tests/TooltipEnterInterrupt.animated.test.tsx +76 -0
  412. package/tests/TooltipGlobalPattern.animated.test.tsx +208 -0
  413. package/tests/TooltipGroup.animated.test.tsx +79 -0
  414. package/tests/TooltipMultiTrigger.test.tsx +116 -0
  415. package/tests/TooltipPositionJump.animated.test.tsx +229 -0
  416. package/tests/TooltipPositionJumpNotes.md +219 -0
  417. package/tests/TooltipRapidSwitch.animated.test.tsx +399 -0
  418. package/tests/TooltipTriggerInline.test.tsx +65 -0
  419. package/tests/TransformMediaQueryMerge.test.tsx +104 -0
  420. package/tests/TransitionEnterExit.animated.test.tsx +311 -0
  421. package/tests/UseTheme.test.tsx +16 -0
  422. package/tests/V5ThemeBuilderOutput.test.tsx +164 -0
  423. package/tests/VariantFontFamily.test.tsx +11 -0
  424. package/tests/VariantsOrder.test.tsx +53 -0
  425. package/tests/_debug_position.mjs +52 -0
  426. package/tests/test-utils.ts +106 -0
  427. package/tests/utils.tsx +54 -0
  428. package/tsconfig.json +45 -0
  429. package/vite-env.d.ts +1 -0
  430. package/vite.config.ts +14 -0
  431. package/webpack.config.js +139 -0
@@ -0,0 +1,526 @@
1
+ import { useRef, useState, useEffect } from 'react'
2
+ import { Button, Paragraph, Square, XStack, YStack, View } from '@hanzo/gui'
3
+
4
+ /**
5
+ * Test case for verifying animation values through console logging
6
+ * This allows Playwright tests to capture actual animation value changes
7
+ * and verify that animations are working correctly.
8
+ *
9
+ * Log format: [ANIM_LOG] id:<testId> prop:<property> value:<value> time:<timestamp>
10
+ */
11
+
12
+ export function AnimationValueLoggingCase() {
13
+ return (
14
+ <YStack gap="$4" padding="$4" flex={1}>
15
+ <Paragraph>Animation Value Logging Tests</Paragraph>
16
+ <Paragraph size="$2" color="$color10">
17
+ Open browser console to see [ANIM_LOG] entries
18
+ </Paragraph>
19
+
20
+ {/* Test 1: Basic opacity animation */}
21
+ <OpacityAnimationTest />
22
+
23
+ {/* Test 2: Transform scale animation */}
24
+ <ScaleAnimationTest />
25
+
26
+ {/* Test 3: Transform translate animation */}
27
+ <TranslateAnimationTest />
28
+
29
+ {/* Test 4: Enter/Exit animation with presence */}
30
+ <EnterExitAnimationTest />
31
+
32
+ {/* Test 5: Color animation */}
33
+ <ColorAnimationTest />
34
+
35
+ {/* Test 6: Animation config override test */}
36
+ <AnimationConfigTest />
37
+ </YStack>
38
+ )
39
+ }
40
+
41
+ /**
42
+ * Test 1: Opacity Animation
43
+ * Toggles opacity from 1 to 0.2 and back
44
+ */
45
+ function OpacityAnimationTest() {
46
+ const [faded, setFaded] = useState(false)
47
+ const lastOpacityRef = useRef<number | null>(null)
48
+ const testId = 'opacity-test'
49
+
50
+ // Create a MutationObserver to track style changes
51
+ const squareRef = useRef<HTMLDivElement>(null)
52
+
53
+ useEffect(() => {
54
+ if (!squareRef.current) return
55
+
56
+ const logOpacity = () => {
57
+ const element = squareRef.current
58
+ if (!element) return
59
+
60
+ const style = getComputedStyle(element)
61
+ const opacity = parseFloat(style.opacity)
62
+
63
+ if (lastOpacityRef.current !== opacity) {
64
+ console.log(
65
+ `[ANIM_LOG] id:${testId} prop:opacity value:${opacity.toFixed(4)} time:${Date.now()}`
66
+ )
67
+ lastOpacityRef.current = opacity
68
+ }
69
+ }
70
+
71
+ // Use requestAnimationFrame loop to capture animation values
72
+ let rafId: number
73
+ let running = true
74
+
75
+ const tick = () => {
76
+ if (!running) return
77
+ logOpacity()
78
+ rafId = requestAnimationFrame(tick)
79
+ }
80
+
81
+ tick()
82
+
83
+ return () => {
84
+ running = false
85
+ cancelAnimationFrame(rafId)
86
+ }
87
+ }, [])
88
+
89
+ return (
90
+ <XStack gap="$4" alignItems="center">
91
+ <Button
92
+ size="$3"
93
+ onPress={() => setFaded(!faded)}
94
+ testID={`${testId}-trigger`}
95
+ data-testid={`${testId}-trigger`}
96
+ >
97
+ Toggle Opacity
98
+ </Button>
99
+ <Square
100
+ ref={squareRef as any}
101
+ transition="quick"
102
+ size={60}
103
+ backgroundColor="$blue10"
104
+ opacity={faded ? 0.2 : 1}
105
+ testID={`${testId}-square`}
106
+ data-testid={`${testId}-square`}
107
+ />
108
+ <Paragraph size="$2" testID={`${testId}-state`} data-testid={`${testId}-state`}>
109
+ {faded ? 'faded' : 'visible'}
110
+ </Paragraph>
111
+ </XStack>
112
+ )
113
+ }
114
+
115
+ /**
116
+ * Test 2: Scale Animation
117
+ * Toggles scale from 1 to 1.5
118
+ */
119
+ function ScaleAnimationTest() {
120
+ const [scaled, setScaled] = useState(false)
121
+ const lastScaleRef = useRef<number | null>(null)
122
+ const testId = 'scale-test'
123
+ const squareRef = useRef<HTMLDivElement>(null)
124
+
125
+ useEffect(() => {
126
+ if (!squareRef.current) return
127
+
128
+ let rafId: number
129
+ let running = true
130
+
131
+ const logScale = () => {
132
+ const element = squareRef.current
133
+ if (!element) return
134
+
135
+ const style = getComputedStyle(element)
136
+ const transform = style.transform
137
+
138
+ // Parse scale from transform matrix: matrix(scaleX, ...)
139
+ let scale = 1
140
+ if (transform && transform !== 'none') {
141
+ const match = transform.match(/matrix\(([^,]+),/)
142
+ if (match && match[1]) {
143
+ const parsed = parseFloat(match[1])
144
+ if (Number.isFinite(parsed)) {
145
+ scale = parsed
146
+ }
147
+ }
148
+ }
149
+
150
+ if (lastScaleRef.current !== scale) {
151
+ console.log(
152
+ `[ANIM_LOG] id:${testId} prop:scale value:${scale.toFixed(4)} time:${Date.now()}`
153
+ )
154
+ lastScaleRef.current = scale
155
+ }
156
+ }
157
+
158
+ const tick = () => {
159
+ if (!running) return
160
+ logScale()
161
+ rafId = requestAnimationFrame(tick)
162
+ }
163
+
164
+ tick()
165
+
166
+ return () => {
167
+ running = false
168
+ cancelAnimationFrame(rafId)
169
+ }
170
+ }, [])
171
+
172
+ return (
173
+ <XStack gap="$4" alignItems="center">
174
+ <Button
175
+ size="$3"
176
+ onPress={() => setScaled(!scaled)}
177
+ testID={`${testId}-trigger`}
178
+ data-testid={`${testId}-trigger`}
179
+ >
180
+ Toggle Scale
181
+ </Button>
182
+ <Square
183
+ ref={squareRef as any}
184
+ transition="quick"
185
+ size={60}
186
+ backgroundColor="$green10"
187
+ scale={scaled ? 1.5 : 1}
188
+ testID={`${testId}-square`}
189
+ data-testid={`${testId}-square`}
190
+ />
191
+ <Paragraph size="$2" testID={`${testId}-state`} data-testid={`${testId}-state`}>
192
+ {scaled ? 'scaled' : 'normal'}
193
+ </Paragraph>
194
+ </XStack>
195
+ )
196
+ }
197
+
198
+ /**
199
+ * Test 3: Translate Y Animation
200
+ * Toggles translateY from 0 to -30
201
+ */
202
+ function TranslateAnimationTest() {
203
+ const [moved, setMoved] = useState(false)
204
+ const lastYRef = useRef<number | null>(null)
205
+ const testId = 'translate-test'
206
+ const squareRef = useRef<HTMLDivElement>(null)
207
+
208
+ useEffect(() => {
209
+ if (!squareRef.current) return
210
+
211
+ let rafId: number
212
+ let running = true
213
+
214
+ const logTranslate = () => {
215
+ const element = squareRef.current
216
+ if (!element) return
217
+
218
+ const style = getComputedStyle(element)
219
+ const transform = style.transform
220
+
221
+ // Parse translateY from transform matrix: matrix(a, b, c, d, tx, ty) - ty is the 6th value
222
+ let y = 0
223
+ if (transform && transform !== 'none') {
224
+ const match = transform.match(
225
+ /matrix\([^,]+,[^,]+,[^,]+,[^,]+,[^,]+,\s*([^)]+)\)/
226
+ )
227
+ if (match && match[1]) {
228
+ const parsed = parseFloat(match[1])
229
+ if (Number.isFinite(parsed)) {
230
+ y = parsed
231
+ }
232
+ }
233
+ }
234
+
235
+ if (lastYRef.current !== y) {
236
+ console.log(
237
+ `[ANIM_LOG] id:${testId} prop:translateY value:${y.toFixed(4)} time:${Date.now()}`
238
+ )
239
+ lastYRef.current = y
240
+ }
241
+ }
242
+
243
+ const tick = () => {
244
+ if (!running) return
245
+ logTranslate()
246
+ rafId = requestAnimationFrame(tick)
247
+ }
248
+
249
+ tick()
250
+
251
+ return () => {
252
+ running = false
253
+ cancelAnimationFrame(rafId)
254
+ }
255
+ }, [])
256
+
257
+ return (
258
+ <XStack gap="$4" alignItems="center">
259
+ <Button
260
+ size="$3"
261
+ onPress={() => setMoved(!moved)}
262
+ testID={`${testId}-trigger`}
263
+ data-testid={`${testId}-trigger`}
264
+ >
265
+ Toggle Y
266
+ </Button>
267
+ <Square
268
+ ref={squareRef as any}
269
+ transition="quick"
270
+ size={60}
271
+ backgroundColor="$blue10"
272
+ y={moved ? -30 : 0}
273
+ testID={`${testId}-square`}
274
+ data-testid={`${testId}-square`}
275
+ />
276
+ <Paragraph size="$2" testID={`${testId}-state`} data-testid={`${testId}-state`}>
277
+ {moved ? 'moved' : 'normal'}
278
+ </Paragraph>
279
+ </XStack>
280
+ )
281
+ }
282
+
283
+ /**
284
+ * Test 4: Enter/Exit Animation with AnimatePresence
285
+ * Tests enterStyle and exitStyle animations
286
+ */
287
+ function EnterExitAnimationTest() {
288
+ const [visible, setVisible] = useState(true)
289
+ const testId = 'enter-exit-test'
290
+ const squareRef = useRef<HTMLDivElement>(null)
291
+ const lastValuesRef = useRef<{ opacity: number; scale: number } | null>(null)
292
+
293
+ useEffect(() => {
294
+ if (!squareRef.current) return
295
+
296
+ let rafId: number
297
+ let running = true
298
+
299
+ const logValues = () => {
300
+ const element = squareRef.current
301
+ if (!element) return
302
+
303
+ const style = getComputedStyle(element)
304
+ const opacity = parseFloat(style.opacity)
305
+
306
+ let scale = 1
307
+ const transform = style.transform
308
+ if (transform && transform !== 'none') {
309
+ const match = transform.match(/matrix\(([^,]+),/)
310
+ if (match && match[1]) {
311
+ const parsed = parseFloat(match[1])
312
+ if (Number.isFinite(parsed)) {
313
+ scale = parsed
314
+ }
315
+ }
316
+ }
317
+
318
+ const current = { opacity: Number.isFinite(opacity) ? opacity : 1, scale }
319
+ const last = lastValuesRef.current
320
+
321
+ if (!last || last.opacity !== current.opacity || last.scale !== current.scale) {
322
+ console.log(
323
+ `[ANIM_LOG] id:${testId} prop:opacity value:${opacity.toFixed(4)} time:${Date.now()}`
324
+ )
325
+ console.log(
326
+ `[ANIM_LOG] id:${testId} prop:scale value:${scale.toFixed(4)} time:${Date.now()}`
327
+ )
328
+ lastValuesRef.current = current
329
+ }
330
+ }
331
+
332
+ const tick = () => {
333
+ if (!running) return
334
+ logValues()
335
+ rafId = requestAnimationFrame(tick)
336
+ }
337
+
338
+ tick()
339
+
340
+ return () => {
341
+ running = false
342
+ cancelAnimationFrame(rafId)
343
+ }
344
+ }, [])
345
+
346
+ return (
347
+ <XStack gap="$4" alignItems="center" height={80}>
348
+ <Button
349
+ size="$3"
350
+ onPress={() => setVisible(!visible)}
351
+ testID={`${testId}-trigger`}
352
+ data-testid={`${testId}-trigger`}
353
+ >
354
+ Toggle Presence
355
+ </Button>
356
+ {visible && (
357
+ <Square
358
+ ref={squareRef as any}
359
+ transition="bouncy"
360
+ size={60}
361
+ backgroundColor="$yellow10"
362
+ enterStyle={{
363
+ opacity: 0,
364
+ scale: 0.5,
365
+ }}
366
+ exitStyle={{
367
+ opacity: 0,
368
+ scale: 0.5,
369
+ }}
370
+ testID={`${testId}-square`}
371
+ data-testid={`${testId}-square`}
372
+ />
373
+ )}
374
+ <Paragraph size="$2" testID={`${testId}-state`} data-testid={`${testId}-state`}>
375
+ {visible ? 'visible' : 'hidden'}
376
+ </Paragraph>
377
+ </XStack>
378
+ )
379
+ }
380
+
381
+ /**
382
+ * Test 5: Color Animation
383
+ * Toggles background color between two colors
384
+ */
385
+ function ColorAnimationTest() {
386
+ const [active, setActive] = useState(false)
387
+ const testId = 'color-test'
388
+ const squareRef = useRef<HTMLDivElement>(null)
389
+ const lastColorRef = useRef<string | null>(null)
390
+
391
+ useEffect(() => {
392
+ if (!squareRef.current) return
393
+
394
+ let rafId: number
395
+ let running = true
396
+
397
+ const logColor = () => {
398
+ const element = squareRef.current
399
+ if (!element) return
400
+
401
+ const style = getComputedStyle(element)
402
+ const color = style.backgroundColor
403
+
404
+ if (lastColorRef.current !== color) {
405
+ console.log(
406
+ `[ANIM_LOG] id:${testId} prop:backgroundColor value:${color} time:${Date.now()}`
407
+ )
408
+ lastColorRef.current = color
409
+ }
410
+ }
411
+
412
+ const tick = () => {
413
+ if (!running) return
414
+ logColor()
415
+ rafId = requestAnimationFrame(tick)
416
+ }
417
+
418
+ tick()
419
+
420
+ return () => {
421
+ running = false
422
+ cancelAnimationFrame(rafId)
423
+ }
424
+ }, [])
425
+
426
+ return (
427
+ <XStack gap="$4" alignItems="center">
428
+ <Button
429
+ size="$3"
430
+ onPress={() => setActive(!active)}
431
+ testID={`${testId}-trigger`}
432
+ data-testid={`${testId}-trigger`}
433
+ >
434
+ Toggle Color
435
+ </Button>
436
+ <Square
437
+ ref={squareRef as any}
438
+ transition="quick"
439
+ size={60}
440
+ backgroundColor={active ? '$red10' : '$blue10'}
441
+ testID={`${testId}-square`}
442
+ data-testid={`${testId}-square`}
443
+ />
444
+ <Paragraph size="$2" testID={`${testId}-state`} data-testid={`${testId}-state`}>
445
+ {active ? 'red' : 'blue'}
446
+ </Paragraph>
447
+ </XStack>
448
+ )
449
+ }
450
+
451
+ /**
452
+ * Test 6: Animation Config Override
453
+ * Tests that animationConfig properly overrides default animation settings
454
+ */
455
+ function AnimationConfigTest() {
456
+ const [expanded, setExpanded] = useState(false)
457
+ const testId = 'config-test'
458
+ const squareRef = useRef<HTMLDivElement>(null)
459
+ const lastWidthRef = useRef<number | null>(null)
460
+
461
+ useEffect(() => {
462
+ if (!squareRef.current) return
463
+
464
+ let rafId: number
465
+ let running = true
466
+
467
+ const logWidth = () => {
468
+ const element = squareRef.current
469
+ if (!element) return
470
+
471
+ const rect = element.getBoundingClientRect()
472
+ const width = Math.round(rect.width)
473
+
474
+ if (lastWidthRef.current !== width) {
475
+ console.log(
476
+ `[ANIM_LOG] id:${testId} prop:width value:${width} time:${Date.now()}`
477
+ )
478
+ lastWidthRef.current = width
479
+ }
480
+ }
481
+
482
+ const tick = () => {
483
+ if (!running) return
484
+ logWidth()
485
+ rafId = requestAnimationFrame(tick)
486
+ }
487
+
488
+ tick()
489
+
490
+ return () => {
491
+ running = false
492
+ cancelAnimationFrame(rafId)
493
+ }
494
+ }, [])
495
+
496
+ return (
497
+ <XStack gap="$4" alignItems="center">
498
+ <Button
499
+ size="$3"
500
+ onPress={() => setExpanded(!expanded)}
501
+ testID={`${testId}-trigger`}
502
+ data-testid={`${testId}-trigger`}
503
+ >
504
+ Toggle Width (slow config)
505
+ </Button>
506
+ <View
507
+ ref={squareRef as any}
508
+ transition="quick"
509
+ // @ts-ignore - animationConfig exists but may not be typed
510
+ animationConfig={{
511
+ type: 'spring',
512
+ damping: 15,
513
+ stiffness: 40, // Slow spring - should take longer than default
514
+ }}
515
+ height={60}
516
+ width={expanded ? 150 : 60}
517
+ backgroundColor="$red10"
518
+ testID={`${testId}-square`}
519
+ data-testid={`${testId}-square`}
520
+ />
521
+ <Paragraph size="$2" testID={`${testId}-state`} data-testid={`${testId}-state`}>
522
+ {expanded ? 'expanded' : 'collapsed'}
523
+ </Paragraph>
524
+ </XStack>
525
+ )
526
+ }
@@ -0,0 +1,110 @@
1
+ import { YStack, XStack, Text, Square } from '@hanzo/gui'
2
+
3
+ /**
4
+ * Test case for animated properties with media queries
5
+ *
6
+ * Bug: With the motion driver, when resizing the viewport and triggering a media query change,
7
+ * the scale property sometimes doesn't apply immediately. It may require multiple resize
8
+ * cycles before taking effect.
9
+ *
10
+ * IMPORTANT: Do NOT use useMedia() here - that would cause a re-render and bypass the bug.
11
+ * The bug is specifically in the useStyleEmitter path which avoids re-renders.
12
+ */
13
+
14
+ export function AnimationsWithMediaQueriesCase() {
15
+ return (
16
+ <YStack p="$4" gap="$6" height={'100vh' as any}>
17
+ <Text fontSize="$5" fontWeight="bold">
18
+ Animations With Media Queries Test
19
+ </Text>
20
+ <Text fontSize="$2" color="$color10">
21
+ Resize window to test. At $sm breakpoint (&lt;660px), styles should change.
22
+ </Text>
23
+
24
+ {/* Test 1: scale only */}
25
+ <YStack gap="$2">
26
+ <Text fontWeight="bold">Test 1: Scale in media query</Text>
27
+ <Text fontSize="$2">Base: scale=1 (blue), $sm: scale=0.75 (green)</Text>
28
+ <XStack height={150} bg="$color3" alignItems="center" justifyContent="center">
29
+ <Square
30
+ testID="test-scale"
31
+ data-testid="test-scale"
32
+ size={100}
33
+ bg="$blue10"
34
+ scale={1}
35
+ transition="quick"
36
+ $sm={{
37
+ scale: 0.75,
38
+ bg: '$green10',
39
+ }}
40
+ />
41
+ </XStack>
42
+ </YStack>
43
+
44
+ {/* Test 2: translateX only */}
45
+ <YStack gap="$2">
46
+ <Text fontWeight="bold">Test 2: TranslateX in media query</Text>
47
+ <Text fontSize="$2">Base: x=0 (purple), $sm: x=50 (orange)</Text>
48
+ <XStack
49
+ height={150}
50
+ bg="$color3"
51
+ alignItems="center"
52
+ justifyContent="center"
53
+ position="relative"
54
+ >
55
+ <YStack
56
+ position="absolute"
57
+ left="50%"
58
+ top={0}
59
+ bottom={0}
60
+ width={1}
61
+ bg="$red10"
62
+ />
63
+ <Square
64
+ testID="test-translate"
65
+ data-testid="test-translate"
66
+ size={100}
67
+ bg="$purple10"
68
+ x={10}
69
+ transition="quick"
70
+ $sm={{
71
+ x: 50,
72
+ bg: '$orange10',
73
+ }}
74
+ />
75
+ </XStack>
76
+ </YStack>
77
+
78
+ {/* Test 3: combined scale + translate (mimics promo badge) */}
79
+ <YStack gap="$2">
80
+ <Text fontWeight="bold">Test 3: Combined scale + translateX</Text>
81
+ <Text fontSize="$2">Base: scale=1, x=-50%, $sm: scale=0.75, x=-90%</Text>
82
+ <XStack height={150} bg="$color3" position="relative" overflow="hidden">
83
+ <XStack
84
+ testID="test-combined"
85
+ data-testid="test-combined"
86
+ position="absolute"
87
+ t={30}
88
+ l="50%"
89
+ x="-50%"
90
+ rounded="$10"
91
+ px="$4"
92
+ py="$2"
93
+ items="center"
94
+ justify="center"
95
+ gap="$2"
96
+ bg="$color5"
97
+ borderWidth={0.5}
98
+ transition="quick"
99
+ $sm={{
100
+ scale: 0.75,
101
+ x: '-90%',
102
+ }}
103
+ >
104
+ <Text>Promo Badge</Text>
105
+ </XStack>
106
+ </XStack>
107
+ </YStack>
108
+ </YStack>
109
+ )
110
+ }