@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
package/package.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "name": "@hanzogui/kitchen-sink",
3
+ "version": "3.0.5",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "start:one": "one dev",
7
+ "start:web": "DISABLE_EXTRACTION=true NODE_ENV=development webpack serve",
8
+ "start:web:prod": "NODE_ENV=production webpack serve",
9
+ "start:web:extract": "DISABLE_EXTRACTION=false NODE_ENV=development webpack serve",
10
+ "start": "EXPO_NO_TELEMETRY=true expo start --dev-client --offline",
11
+ "start:extract": "HANZO_GUI_OPTIMIZE_NATIVE_VIEWS=1 HANZO_GUI_ENABLE_DYNAMIC_LOAD=1 bun run start",
12
+ "start:prod": "DISABLE_EXTRACTION=false HANZO_GUI_ENABLE_DYNAMIC_LOAD=1 expo start --dev-client --offline --no-dev --minify",
13
+ "start:gui": "tama dev",
14
+ "start:android": "bun run start --android",
15
+ "start:ios": "bun run start --ios",
16
+ "start:clean": "watchman watch-del-all & rm -r $TMPDIR/metro-cache & bun run start -c",
17
+ "pod": "./pod-install.sh",
18
+ "android": "EXPO_NO_TELEMETRY=true expo run:android",
19
+ "ios": "bun run pod && EXPO_NO_TELEMETRY=true expo run:ios",
20
+ "ios:prod": "bun run ios --configuration Release",
21
+ "eject": "EXPO_NO_TELEMETRY=true expo eject",
22
+ "screenshot": "node -r esbuild-register ../../node_modules/.bin/playwright test --config ./playwright-screenshot.config.ts",
23
+ "test:native:ios": "bun run ../packages/native-ci/src/cli.ts test ios --project-root .",
24
+ "test:native:android": "bun run ../packages/native-ci/src/cli.ts test android --project-root .",
25
+ "test:native:maestro": "bun run ../packages/native-ci/src/cli.ts test maestro --project-root .",
26
+ "test:web": "bun run-tests-parallel.ts",
27
+ "test:web:seq": "NODE_ENV=test node -r esbuild-register ../../node_modules/.bin/playwright test",
28
+ "test:web:driver": "NODE_ENV=test node -r esbuild-register ../../node_modules/.bin/playwright test",
29
+ "test:web:debug": "NODE_ENV=test node -r esbuild-register ../../node_modules/.bin/playwright test --debug",
30
+ "detox:build:ios": "bun run pod && detox build -c ios.sim.debug",
31
+ "detox:build:android": "detox build -c android.emu.debug",
32
+ "detox:run:ios": "./run-detox.sh ios",
33
+ "detox:run:android": "./run-detox.sh android",
34
+ "prod:web": "NODE_ENV=production webpack --json=dist/compilation-stats.json",
35
+ "test:native": "bun run test:native:ios && bun run test:native:maestro",
36
+ "test": "bun run test:web && ./run-native-tests.sh"
37
+ },
38
+ "dependencies": {
39
+ "@dominicstop/ts-event-emitter": "1.1.0",
40
+ "@react-native-async-storage/async-storage": "2.2.0",
41
+ "@react-native-menu/menu": "^2.0.0",
42
+ "@react-navigation/native": "^7.0.14",
43
+ "@react-navigation/native-stack": "^7.2.0",
44
+ "@shopify/restyle": "^2.4.4",
45
+ "@hanzogui/animations-css": "3.0.5",
46
+ "@hanzogui/animations-motion": "3.0.5",
47
+ "@hanzogui/animations-react-native": "3.0.5",
48
+ "@hanzogui/animations-reanimated": "3.0.5",
49
+ "@hanzogui/colors": "3.0.5",
50
+ "@hanzogui/config": "3.0.5",
51
+ "@hanzogui/constants": "3.0.5",
52
+ "@hanzogui/core": "3.0.5",
53
+ "@hanzogui/demos": "3.0.5",
54
+ "@hanzogui/font-inter": "3.0.5",
55
+ "@hanzogui/get-token": "3.0.5",
56
+ "@hanzogui/lucide-icons-2": "3.0.5",
57
+ "@hanzogui/native": "3.0.5",
58
+ "@hanzogui/sandbox-ui": "3.0.5",
59
+ "@hanzogui/shorthands": "3.0.5",
60
+ "@hanzogui/theme": "3.0.5",
61
+ "@hanzogui/themes": "3.0.5",
62
+ "@hanzogui/web": "3.0.5",
63
+ "burnt": "^0.12.2",
64
+ "expo": "~55.0.6",
65
+ "expo-constants": "~55.0.7",
66
+ "expo-document-picker": "~55.0.8",
67
+ "expo-font": "~55.0.4",
68
+ "expo-image-picker": "~55.0.12",
69
+ "expo-linear-gradient": "~55.0.8",
70
+ "expo-linking": "~55.0.7",
71
+ "expo-splash-screen": "~55.0.8",
72
+ "react": ">=19",
73
+ "react-dom": "*",
74
+ "react-native": "0.83.2",
75
+ "react-native-actions-sheet": "^10.1.2",
76
+ "react-native-gesture-handler": "~2.30.0",
77
+ "react-native-ios-context-menu": "^3.2.1",
78
+ "react-native-ios-utilities": "^5.2.0",
79
+ "react-native-keyboard-controller": "1.20.7",
80
+ "react-native-launch-arguments": "^4.1.1",
81
+ "react-native-reanimated": "~4.2.2",
82
+ "react-native-safe-area-context": "~5.7.0",
83
+ "react-native-screens": "~4.23.0",
84
+ "react-native-svg": "15.15.3",
85
+ "react-native-teleport": "^1.0.0",
86
+ "react-native-web": "^0.21.0",
87
+ "react-native-worklets": "0.7.2",
88
+ "sf-symbols-typescript": "^2.2.0",
89
+ "solito": "^4.3.0",
90
+ "@hanzo/gui": "3.0.5",
91
+ "vitest": "4.0.4",
92
+ "zeego": "^3.0.0"
93
+ },
94
+ "devDependencies": {
95
+ "@babel/core": "^7.25.2",
96
+ "@expo/fingerprint": "~0.16.6",
97
+ "@playwright/test": "^1.49.1",
98
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
99
+ "@hanzogui/babel-plugin": "3.0.5",
100
+ "@hanzogui/metro-plugin": "3.0.5",
101
+ "@types/jest": "29.5.14",
102
+ "@types/pngjs": "^6.0.5",
103
+ "babel-plugin-module-resolver": "^5.0.2",
104
+ "detox": "^20.46.0",
105
+ "html-webpack-plugin": "^5.5.0",
106
+ "jest": "^29",
107
+ "mini-css-extract-plugin": "^2.9.1",
108
+ "one": "1.12.5",
109
+ "pngjs": "^7.0.0",
110
+ "pod-install": "^0.3.2",
111
+ "tilg": "0.1.1",
112
+ "ts-jest": "^29.4.5",
113
+ "webpack": "^5.88.2",
114
+ "webpack-cli": "^4.9.2",
115
+ "webpack-dev-server": "^4.8.1"
116
+ },
117
+ "packageManager": "bun@1.3.9"
118
+ }
@@ -0,0 +1,471 @@
1
+ # Toast v2 Implementation Plan
2
+
3
+ ## Overview
4
+
5
+ Revamp @hanzogui/toast to v2, inspired by Sonner's excellent UX. Must be fully cross-platform using Hanzo GUI's animation system - NO CSS cheats.
6
+
7
+ ## Reference Implementations
8
+
9
+ - ~/github/sonner - primary inspiration
10
+ - ~/github/base-ui - additional patterns
11
+ - @hanzogui/sheet - gesture/drag patterns, resistive pull
12
+
13
+ ---
14
+
15
+ ## Current Session Issues Found & Fixes
16
+
17
+ ### BUGS FOUND (need fixing)
18
+
19
+ 1. **Top position toasts outside frame** ✅ FIXED
20
+ - Issue: Toasts with top position were rendering outside the container
21
+ - Fix: Changed from hardcoded `bottom: 0` to dynamic `{...(isTop ? { top: 0 } : { bottom: 0 })}`
22
+
23
+ 2. **Action buttons overlapping** ✅ FIXED
24
+ - Issue: Cancel/Confirm buttons used ToastCloseButton (20x20px fixed) causing overlap
25
+ - Fix: Created new ToastActionButton component with proper padding for text buttons
26
+
27
+ 3. **Hover stack → leave → rest fly away, one stays** ✅ FIXED
28
+ - Issue: When hovering stacked toasts then leaving, most toasts dismiss but one stays longer
29
+ - Cause: pauseTimer was being called multiple times, double-counting elapsed time
30
+ - Fix: Added `lastPauseTimeRef` guard (Sonner pattern) - only calculate elapsed time if timer was started after last pause
31
+
32
+ 4. **Exit animations fly too far** ✅ FIXED
33
+ - Issue: Toasts flew 100px on exit, too dramatic
34
+ - Fix: Reduced to 30px for swipe, 10px for normal exit
35
+
36
+ 5. **Focus outline shows on click** ✅ FIXED
37
+ - Issue: Focus ring appeared on mouse click, should only show on keyboard
38
+ - Fix: Changed `focusStyle` to `focusVisibleStyle`
39
+
40
+ 6. **Expanded state showed ALL toasts** ✅ FIXED
41
+ - Issue: When expanded, ALL toasts showed instead of respecting visibleToasts limit
42
+ - Sonner behavior: visibleToasts limit applies in BOTH collapsed and expanded states
43
+ - Fix: Changed opacity logic to hide toasts beyond visibleToasts in both states
44
+ - Also added `pointerEvents: 'none'` for hidden toasts
45
+
46
+ ### CHANGES MADE THIS SESSION
47
+
48
+ 1. **visibleToasts default: 3 → 4**
49
+ 2. **Fade out last visible toast** - opacity 0.5 for toast at visibleToasts-1 index
50
+ 3. **Top position anchor** - dynamic top/bottom based on position
51
+ 4. **ToastActionButton component** - proper text button for action/cancel
52
+ 5. **Subtle exit animations** - 10px/30px instead of 100px
53
+ 6. **focusVisibleStyle** - outline only on keyboard navigation
54
+
55
+ ### DESIGN DECISIONS (user feedback)
56
+
57
+ 1. **Keep styles minimal in core** - demo can add more styles
58
+ 2. **No sonnerStyle close button** - keep it simple, inline close button is fine
59
+ 3. **Use animateOnly={['transform', 'opacity']}** in examples for performance
60
+ 4. **Export .Close component** - like Dialog, just wraps events without styling
61
+
62
+ ---
63
+
64
+ ## Style Checklist
65
+
66
+ ### Container (Toaster)
67
+
68
+ - [x] position: fixed (web) / absolute (native)
69
+ - [x] z-index: 100000+ (very high)
70
+ - [x] width: 356px (TOAST_WIDTH constant)
71
+ - [x] Viewport offsets: 24px desktop
72
+ - [x] pointerEvents: 'box-none' for pass-through
73
+
74
+ ### Position Variants
75
+
76
+ - [x] bottom-right: bottom + right offsets
77
+ - [x] bottom-left: bottom + left offsets
78
+ - [x] bottom-center: bottom + left 50% + translateX(-50%)
79
+ - [x] top-right: top + right offsets ✅ FIXED anchor
80
+ - [x] top-left: top + left offsets ✅ FIXED anchor
81
+ - [x] top-center: top + left 50% + translateX(-50%) ✅ FIXED anchor
82
+
83
+ ### Toast Item Frame
84
+
85
+ - [x] position: absolute (within container)
86
+ - [x] left: 0, right: 0 (full width of container)
87
+ - [x] **Dynamic anchor: top:0 for top positions, bottom:0 for bottom positions** ✅ FIXED
88
+ - [x] background: $background
89
+ - [x] border-radius: $4 (8px)
90
+ - [x] paddingHorizontal: $4, paddingVertical: $3
91
+ - [x] border: 1px solid $borderColor
92
+ - [x] elevation: $4 + shadow for depth
93
+ - [x] focusable: true
94
+ - [x] **focusVisibleStyle instead of focusStyle** ✅ FIXED
95
+
96
+ ### Toast Content Layout
97
+
98
+ - [x] flex row with icon, content, close button
99
+ - [x] icon: 16x16px, flex-shrink: 0
100
+ - [x] content: flex column, gap $1
101
+ - [x] title: fontWeight 600, $color, size $4
102
+ - [x] description: $color11, size $2
103
+ - [x] gap: $3 between elements
104
+
105
+ ### Close Button
106
+
107
+ - [x] positioned inline (user decided against absolute overlap)
108
+ - [x] 20x20px circle
109
+ - [x] borderRadius: $10 (circular)
110
+ - [x] backgroundColor: $color5
111
+ - [x] hoverStyle: $color6
112
+ - [x] pressStyle: $color7
113
+
114
+ ### Action Buttons ✅ FIXED
115
+
116
+ - [x] **New ToastActionButton component** with proper sizing
117
+ - [x] borderRadius: $2
118
+ - [x] paddingHorizontal: $2
119
+ - [x] height: 24px
120
+ - [x] primary variant for action button (dark bg, light text)
121
+ - [x] marginTop: $3 spacing
122
+ - [x] gap: $2 between buttons
123
+ - [x] justifyContent: flex-end
124
+
125
+ ### Rich Colors (Type Variants)
126
+
127
+ - [x] success: $green2 background, $green6 border
128
+ - [x] error: $red2 background, $red6 border
129
+ - [x] warning: $yellow2 background, $yellow6 border
130
+ - [x] info: $blue2 background, $blue6 border
131
+ - [x] loading: default (neutral)
132
+
133
+ ### Icons
134
+
135
+ - [x] success: ✓ in $green10
136
+ - [x] error: ✕ in $red10
137
+ - [x] warning: ⚠ in $yellow10
138
+ - [x] info: ℹ in $blue10
139
+ - [x] loading: ⟳ in $color11
140
+ - [x] close: ✕ in $color11
141
+
142
+ ---
143
+
144
+ ## Feature Checklist
145
+
146
+ ### Core Toast API
147
+
148
+ - [x] toast() - basic toast
149
+ - [x] toast.success() - success type
150
+ - [x] toast.error() - error type
151
+ - [x] toast.warning() - warning type
152
+ - [x] toast.info() - info type
153
+ - [x] toast.loading() - loading type (no auto-dismiss)
154
+ - [x] toast.promise() - promise with loading/success/error states
155
+ - [x] toast.custom() - custom JSX
156
+ - [x] toast.dismiss(id) - dismiss specific toast
157
+ - [x] toast.dismiss() - dismiss all
158
+
159
+ ### Toast Options
160
+
161
+ - [x] id - custom id for updating
162
+ - [x] title - main text (string or function)
163
+ - [x] description - secondary text (string or function)
164
+ - [x] duration - auto-dismiss time (default 4000ms)
165
+ - [x] icon - custom icon
166
+ - [x] action - action button with label/onClick
167
+ - [x] cancel - cancel button
168
+ - [x] dismissible - can be dismissed (default true)
169
+ - [x] onDismiss - callback when dismissed
170
+ - [x] onAutoClose - callback when auto-closed
171
+ - [x] closeButton - per-toast close button override
172
+
173
+ ### Toaster Props
174
+
175
+ - [x] position - 6 positions
176
+ - [x] expand - always show expanded
177
+ - [x] **visibleToasts - max visible (default 4)** ✅ CHANGED from 3
178
+ - [x] gap - space between toasts (default 14px)
179
+ - [x] duration - default duration (4000ms)
180
+ - [x] offset - viewport padding (24px)
181
+ - [x] hotkey - keyboard shortcut (alt+T)
182
+ - [x] swipeDirection - dismiss direction ('right')
183
+ - [x] swipeThreshold - swipe distance (50px)
184
+ - [x] closeButton - show close buttons
185
+ - [x] richColors - colored backgrounds
186
+ - [x] icons - custom icons per type
187
+ - [x] theme - light/dark/system
188
+
189
+ ### Stacking Behavior
190
+
191
+ - [x] Only show visibleToasts (default 4)
192
+ - [x] Scale down non-front toasts: `1 - (index * 0.05)`
193
+ - [x] Y-offset for collapsed stack: 10px per toast
194
+ - [x] Expanded state shows full offset with gaps
195
+ - [x] Front toast height applied to hidden toasts
196
+ - [x] z-index: `visibleToasts - index` (front highest)
197
+ - [x] transformOrigin: 'bottom center' for bottom, 'top center' for top
198
+ - [x] **Fade out last visible toast (opacity 0.5)** ✅ NEW
199
+
200
+ ### Hover Expand ✅ COMPLETE
201
+
202
+ - [x] Expand on hover (onMouseEnter + onMouseMove)
203
+ - [x] Pause timers when expanded/hovered
204
+ - [x] Resume timers when mouse leaves
205
+ - [x] **Gap filler View to prevent flicker when mouse moves between toasts**
206
+ - [x] Collapse when only 1 toast remains
207
+ - [x] interacting state tracks pointer down/up
208
+ - [x] **Timer sync issue when leaving hover** ✅ FIXED with lastPauseTimeRef guard
209
+
210
+ ### Swipe to Dismiss ✅ COMPLETE
211
+
212
+ - [x] Pointer event tracking (setPointerCapture)
213
+ - [x] Direction lock on first significant movement
214
+ - [x] Threshold-based dismiss (50px default)
215
+ - [x] Velocity-based dismiss (0.11 px/ms)
216
+ - [x] **Resistive pull in wrong direction (sqrt curve from Sheet)**
217
+ - [x] Exit animation in swipe direction
218
+ - [x] Snap back on cancel
219
+
220
+ ### Enter/Exit Animations ✅ REFINED
221
+
222
+ - [x] enterStyle: opacity 0, y: ±10, scale: 0.95 (subtle)
223
+ - [x] exitStyle: opacity 0, x/y: ±30 for swipe, ±10 for normal, scale: 0.95
224
+ - [x] AnimatePresence for mount/unmount
225
+ - [x] transition: 'quick' (Gui animation)
226
+ - [x] Disable animation while dragging
227
+
228
+ ### Keyboard Support
229
+
230
+ - [x] Escape to dismiss focused toast
231
+ - [x] Hotkey to expand toaster (alt+T)
232
+ - [x] Focus management (tabIndex, lastFocusedElementRef)
233
+
234
+ ### Accessibility
235
+
236
+ - [x] role="status"
237
+ - [x] aria-live="polite"
238
+ - [x] aria-atomic
239
+ - [x] aria-label on container
240
+ - [x] tabIndex for focusable
241
+ - [x] aria-label="Close toast" on close button
242
+
243
+ ---
244
+
245
+ ## Test Checklist
246
+
247
+ ### Basic Toast Tests ✅
248
+
249
+ - [x] shows a default toast
250
+ - [x] shows typed toasts (success, error, warning, info)
251
+ - [x] shows loading toast
252
+ - [x] shows multiple stacked toasts
253
+
254
+ ### Interaction Tests ✅
255
+
256
+ - [x] dismisses all toasts
257
+ - [x] closes toast when clicking close button
258
+ - [x] keyboard escape dismisses focused toast
259
+ - [x] shows action button
260
+
261
+ ### Promise Tests ✅
262
+
263
+ - [x] promise toast transitions loading -> success
264
+ - [x] promise toast shows error on rejection
265
+
266
+ ### Position Tests ✅
267
+
268
+ - [x] changes position when clicking position buttons
269
+ - [x] all 6 positions verified with screenshots
270
+
271
+ ### Hover Tests ✅
272
+
273
+ - [x] hover expands stacked toasts
274
+ - [x] hover pauses auto-dismiss timer
275
+ - [x] mouse leave collapses stack
276
+ - [x] **no flicker when mouse moves between toasts**
277
+
278
+ ### Swipe Tests ✅
279
+
280
+ - [x] swipe right dismisses (default)
281
+ - [x] swipe threshold works
282
+ - [x] velocity-based dismiss
283
+ - [x] resistive pull in wrong direction
284
+ - [x] swipe cancel snaps back
285
+
286
+ ### Interrupt Tests ✅ NEW
287
+
288
+ - [x] toast closing does not interrupt on mouse re-entry
289
+ - [x] drag gesture moves toast visually
290
+ - [x] fast swipe dismisses via velocity
291
+
292
+ ---
293
+
294
+ ## TODO - Remaining Work (DEADLINE: 9:00 AM DEMO VIDEO)
295
+
296
+ ### TIMELINE
297
+
298
+ - **NOW - 8:20**: Fix top position bug, verify tests pass
299
+ - **8:20 - 8:35**: Write clean ToastDemo, verify on gui.hanzo.ai /ui/toast (mobile + safe areas)
300
+ - **8:35 - 8:45**: Update docs, update version-two blog post
301
+ - **8:45 - 8:55**: Full yarn test, lint, typecheck, sub-agent review
302
+ - **8:55 - 9:00**: Clean commit, push to CI, /alert user
303
+
304
+ ### CRITICAL - Before 8:20
305
+
306
+ 1. [x] **Fix timer sync bug** ✅ DONE - added lastPauseTimeRef guard
307
+ 2. [x] **FIX: Top position toast outside viewport** ✅ FIXED - explicitly set top/bottom to avoid conflicts
308
+ 3. [x] Test action buttons after ToastActionButton fix ✅ VERIFIED - buttons render correctly
309
+
310
+ ### Before 8:35 (Demo Ready)
311
+
312
+ 4. [x] Write clean ToastDemo for gui.hanzo.ai ✅ DONE - code/demos/src/ToastDemo.tsx
313
+ 5. [x] Verify on yarn dev site at /ui/toast ✅ VERIFIED - page renders, toast works
314
+ 6. [x] Mobile web + safe areas check (SSR safe!) ✅ FIXED - use-window-dimensions isClient guard
315
+ 7. [ ] Web-only code but use conditionals for future native support
316
+
317
+ ### Before 8:45 (Docs + Blog)
318
+
319
+ 8. [ ] Update Toast docs - clean up (2.0.0.mdx exists but has old API docs)
320
+ 9. [ ] Update version-two blog post with Toast feature/demo hero
321
+
322
+ ### Before 8:55 (Testing + Review)
323
+
324
+ 10. [x] yarn test - 31 toast tests passing ✅
325
+ 11. [x] yarn lint, yarn typecheck ✅ - fixed biome issues, types clean
326
+ 12. [ ] Sub-agent code review
327
+
328
+ ### Before 9:00 (Ship It)
329
+
330
+ 13. [ ] Clean commit and push to CI
331
+ 14. [ ] /alert user every 30s until acknowledged
332
+
333
+ ### Low Priority (Post-Demo)
334
+
335
+ - [ ] Export .Close component (Dialog pattern)
336
+ - [ ] Add animateOnly={['transform', 'opacity']} to examples
337
+ - [ ] All animation drivers tested
338
+ - [ ] SVG icons instead of text characters
339
+ - [ ] RTL support
340
+
341
+ ---
342
+
343
+ ## Key Formulas (from Sonner)
344
+
345
+ ### Stack Scale
346
+
347
+ ```
348
+ scale = 1 - (index * 0.05)
349
+ // index 0: 1.0, index 1: 0.95, index 2: 0.90
350
+ ```
351
+
352
+ ### Collapsed Y Offset
353
+
354
+ ```
355
+ // For bottom position
356
+ stackY = isFront ? 0 : -peekAmount * index
357
+ // For top position
358
+ stackY = isFront ? 0 : peekAmount * index
359
+ ```
360
+
361
+ ### Expanded Y Offset
362
+
363
+ ```
364
+ offset = (heightIndex * gap) + toastsHeightBefore
365
+ // For bottom: -offset
366
+ // For top: +offset
367
+ ```
368
+
369
+ ### Resistive Pull (from Sheet)
370
+
371
+ ```typescript
372
+ function resisted(delta: number, maxResist = 25): number {
373
+ if (delta >= 0) return delta
374
+ const pastBoundary = Math.abs(delta)
375
+ const resistedDistance = Math.sqrt(pastBoundary) * 2
376
+ return -Math.min(resistedDistance, maxResist)
377
+ }
378
+ ```
379
+
380
+ ### Velocity Threshold
381
+
382
+ ```
383
+ VELOCITY_THRESHOLD = 0.11 // px/ms
384
+ shouldDismiss = passedThreshold || velocity > VELOCITY_THRESHOLD
385
+ ```
386
+
387
+ ### Gap Filler (prevents hover flicker)
388
+
389
+ ```typescript
390
+ // Invisible hit area above/below toast when expanded
391
+ const gapFillerHeight = expanded ? gap + 1 : 0
392
+ <View
393
+ position="absolute"
394
+ left={0}
395
+ right={0}
396
+ height={gapFillerHeight}
397
+ pointerEvents="auto"
398
+ {...(isTop ? { top: '100%' } : { bottom: '100%' })}
399
+ />
400
+ ```
401
+
402
+ ### Opacity Fade for Limit
403
+
404
+ ```typescript
405
+ // Fade out toasts as they approach visibility limit
406
+ let computedOpacity = 1
407
+ if (!expanded) {
408
+ if (index >= visibleToasts) {
409
+ computedOpacity = 0 // completely hidden beyond limit
410
+ } else if (index === visibleToasts - 1) {
411
+ computedOpacity = 0.5 // last visible toast fades
412
+ }
413
+ }
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Files Modified
419
+
420
+ 1. `/code/ui/toast/src/Toaster.tsx`
421
+ - Container positioning with minHeight: 1
422
+ - onMouseEnter + onMouseMove for hover expand
423
+ - Auto-collapse when 1 toast remains
424
+ - **visibleToasts default: 4**
425
+
426
+ 2. `/code/ui/toast/src/ToastItem.tsx`
427
+ - Stacking logic (scale, y, z-index, height, transformOrigin)
428
+ - Gap filler View for hover flicker prevention
429
+ - dataSet for RN Web data attribute compatibility
430
+ - Enter/exit styles with AnimatePresence
431
+ - **Dynamic top/bottom anchor based on position**
432
+ - **ToastActionButton component for action/cancel**
433
+ - **focusVisibleStyle for keyboard-only focus**
434
+ - **Subtle exit animations (10px/30px)**
435
+ - **Opacity fade for limit**
436
+
437
+ 3. `/code/ui/toast/src/useDragGesture.ts`
438
+ - Resistive pull with sqrt curve (Sheet pattern)
439
+ - Direction lock on first movement
440
+ - Velocity-based dismiss
441
+
442
+ 4. `/code/kitchen-sink/tests/ToastMultiple.test.tsx`
443
+ - Loading toast test fix (text selector vs data-type)
444
+
445
+ 5. `/code/kitchen-sink/tests/ToastHover.test.tsx` - NEW
446
+ - Hover expand tests
447
+ - Flicker prevention tests
448
+ - Timer pause tests
449
+
450
+ 6. `/code/kitchen-sink/tests/ToastVisual.test.tsx` - NEW
451
+ - Visual verification tests
452
+ - Swipe tests
453
+
454
+ 7. `/code/kitchen-sink/tests/ToastInterrupt.test.tsx` - NEW
455
+ - Interrupt behavior tests
456
+ - Drag gesture tests
457
+ - Velocity dismiss tests
458
+
459
+ ---
460
+
461
+ ## Test Results Summary
462
+
463
+ **Total: 25 tests passing**
464
+
465
+ - Toast.test.tsx: 3 tests (focus management)
466
+ - ToastMultiple.test.tsx: 12 tests (core API)
467
+ - ToastHover.test.tsx: 3 tests (hover behavior)
468
+ - ToastVisual.test.tsx: 4 tests (swipe, visual)
469
+ - ToastInterrupt.test.tsx: 3 tests (interrupt, drag, velocity)
470
+
471
+ All tests pass with CSS animation driver.
@@ -0,0 +1,71 @@
1
+ import { defineConfig, devices } from '@playwright/test'
2
+ import { ANIMATION_DRIVERS } from './tests/test-utils'
3
+
4
+ const port = process.env.PORT || '9000'
5
+
6
+ // Support both single-driver mode (via env var) and multi-driver parallel mode
7
+ const singleDriver = process.env.HANZO_GUI_TEST_ANIMATION_DRIVER
8
+ const drivers = singleDriver ? [singleDriver] : [...ANIMATION_DRIVERS]
9
+
10
+ /**
11
+ * Test organization:
12
+ * - *.animated.test.ts - Animation-dependent tests, run with ALL animation drivers
13
+ * - *.test.ts (non-animated) - Style/functional tests, run ONCE with default driver
14
+ *
15
+ * This significantly speeds up the test suite since most tests don't need
16
+ * to run 4x across all animation drivers.
17
+ */
18
+ export default defineConfig({
19
+ // Look for test files in the "tests" directory, relative to this configuration file.
20
+ testDir: 'tests',
21
+ reporter: [['list']],
22
+
23
+ use: {
24
+ // Base URL to use in actions like `await page.goto('/')`.
25
+ baseURL: `http://localhost:${port}`,
26
+ // Larger viewport to prevent popover positioning issues
27
+ viewport: { width: 1920, height: 1080 },
28
+ },
29
+
30
+ projects: [
31
+ // Non-animated tests run once with default driver (native)
32
+ {
33
+ name: 'default',
34
+ testIgnore: '**/*.animated.test.{ts,tsx}',
35
+ metadata: { animationDriver: 'native' },
36
+ },
37
+ // WebKit project scoped to RemoveScroll tests (scroll restoration)
38
+ {
39
+ name: 'webkit',
40
+ use: { ...devices['Desktop Safari'] },
41
+ testMatch: '**/RemoveScroll.test.{ts,tsx}',
42
+ metadata: { animationDriver: 'native' },
43
+ },
44
+ // Animated tests run with all animation drivers
45
+ ...drivers.map((driver) => ({
46
+ name: `animated-${driver}`,
47
+ testMatch: '**/*.animated.test.{ts,tsx}',
48
+ // AnimationsWithMediaQueries only passes with css and motion drivers for now
49
+ ...(driver !== 'motion' &&
50
+ driver !== 'css' && {
51
+ testIgnore: '**/AnimationsWithMediaQueries.animated.test.{ts,tsx}',
52
+ }),
53
+ metadata: { animationDriver: driver },
54
+ })),
55
+ ],
56
+
57
+ // Run your local dev server before starting the tests.
58
+ // When run-tests-parallel.ts manages the server, REUSE_SERVER is set to skip launching another.
59
+ webServer: {
60
+ command: `PORT=${port} bun run start:web`,
61
+ url: `http://localhost:${port}`,
62
+ reuseExistingServer: !!process.env.REUSE_SERVER,
63
+ timeout: 120_000, // give webpack more time to start
64
+ },
65
+
66
+ fullyParallel: true,
67
+ workers: process.env.CI ? 2 : 4,
68
+ retries: process.env.CI ? 2 : 1,
69
+
70
+ timeout: 50_000,
71
+ })