@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,220 @@
1
+ import { expect, test } from '@playwright/test'
2
+
3
+ import { setupPage } from './test-utils'
4
+
5
+ test.describe('Menu Submenu Keyboard Focus', () => {
6
+ test.beforeEach(async ({ page }) => {
7
+ await setupPage(page, { name: 'MenuAccessibilityCase', type: 'useCase' })
8
+ })
9
+
10
+ test('submenu trigger should have focusVisible style when opened via ArrowRight', async ({
11
+ page,
12
+ }) => {
13
+ await page.waitForLoadState('networkidle')
14
+
15
+ // open menu via keyboard
16
+ const trigger = page.getByTestId('menu-trigger')
17
+ await trigger.focus()
18
+ await page.keyboard.press('Enter')
19
+ await page.waitForTimeout(300)
20
+
21
+ const menuContent = page.getByTestId('menu-content')
22
+ await expect(menuContent).toBeVisible()
23
+
24
+ // navigate to submenu trigger via keyboard
25
+ const submenuTrigger = page.getByTestId('submenu-trigger')
26
+ await submenuTrigger.focus()
27
+ await expect(submenuTrigger).toBeFocused()
28
+
29
+ // press ArrowRight to open submenu
30
+ await page.keyboard.press('ArrowRight')
31
+ await page.waitForTimeout(300)
32
+
33
+ const submenuContent = page.getByTestId('submenu-content')
34
+ await expect(submenuContent).toBeVisible()
35
+
36
+ // the first submenu item should be focused AND have focusVisible
37
+ const firstSubmenuItem = page.getByTestId('submenu-item-1')
38
+ await expect(firstSubmenuItem).toBeFocused()
39
+
40
+ // check that the focused item has the data-highlighted attribute (indicates focus style)
41
+ const hasHighlight = await firstSubmenuItem.getAttribute('data-highlighted')
42
+ expect(hasHighlight).toBe('')
43
+ })
44
+
45
+ test('submenu trigger should have focusVisible style when opened via Enter', async ({
46
+ page,
47
+ }) => {
48
+ await page.waitForLoadState('networkidle')
49
+
50
+ // open menu via keyboard
51
+ const trigger = page.getByTestId('menu-trigger')
52
+ await trigger.focus()
53
+ await page.keyboard.press('Enter')
54
+ await page.waitForTimeout(300)
55
+
56
+ const menuContent = page.getByTestId('menu-content')
57
+ await expect(menuContent).toBeVisible()
58
+
59
+ // navigate to submenu trigger via keyboard
60
+ const submenuTrigger = page.getByTestId('submenu-trigger')
61
+ await submenuTrigger.focus()
62
+ await expect(submenuTrigger).toBeFocused()
63
+
64
+ // press Enter to open submenu
65
+ await page.keyboard.press('Enter')
66
+ await page.waitForTimeout(300)
67
+
68
+ const submenuContent = page.getByTestId('submenu-content')
69
+ await expect(submenuContent).toBeVisible()
70
+
71
+ // the first submenu item should be focused AND have focusVisible
72
+ const firstSubmenuItem = page.getByTestId('submenu-item-1')
73
+ await expect(firstSubmenuItem).toBeFocused()
74
+
75
+ // check that the focused item has the data-highlighted attribute
76
+ const hasHighlight = await firstSubmenuItem.getAttribute('data-highlighted')
77
+ expect(hasHighlight).toBe('')
78
+ })
79
+
80
+ test('submenu trigger should have focusVisible when escape returns focus from submenu', async ({
81
+ page,
82
+ }) => {
83
+ await page.waitForLoadState('networkidle')
84
+
85
+ // open menu via keyboard
86
+ const trigger = page.getByTestId('menu-trigger')
87
+ await trigger.focus()
88
+ await page.keyboard.press('Enter')
89
+ await page.waitForTimeout(300)
90
+
91
+ const menuContent = page.getByTestId('menu-content')
92
+ await expect(menuContent).toBeVisible()
93
+
94
+ // navigate to submenu trigger and open via keyboard
95
+ const submenuTrigger = page.getByTestId('submenu-trigger')
96
+ await submenuTrigger.focus()
97
+ await page.keyboard.press('ArrowRight')
98
+ await page.waitForTimeout(300)
99
+
100
+ const submenuContent = page.getByTestId('submenu-content')
101
+ await expect(submenuContent).toBeVisible()
102
+
103
+ // press Escape to close submenu
104
+ await page.keyboard.press('Escape')
105
+ await page.waitForTimeout(300)
106
+
107
+ // submenu should be closed
108
+ await expect(submenuContent).not.toBeVisible()
109
+
110
+ // parent menu should still be open
111
+ await expect(menuContent).toBeVisible()
112
+
113
+ // focus should return to submenu trigger WITH focusVisible
114
+ await expect(submenuTrigger).toBeFocused()
115
+
116
+ // check that the submenu trigger has the data-highlighted attribute (focus visible)
117
+ const hasHighlight = await submenuTrigger.getAttribute('data-highlighted')
118
+ expect(hasHighlight).toBe('')
119
+ })
120
+
121
+ test('submenu trigger should have focusVisible when ArrowLeft returns focus from submenu', async ({
122
+ page,
123
+ }) => {
124
+ await page.waitForLoadState('networkidle')
125
+
126
+ // open menu via keyboard
127
+ const trigger = page.getByTestId('menu-trigger')
128
+ await trigger.focus()
129
+ await page.keyboard.press('Enter')
130
+ await page.waitForTimeout(300)
131
+
132
+ const menuContent = page.getByTestId('menu-content')
133
+ await expect(menuContent).toBeVisible()
134
+
135
+ // navigate to submenu trigger and open via keyboard
136
+ const submenuTrigger = page.getByTestId('submenu-trigger')
137
+ await submenuTrigger.focus()
138
+ await page.keyboard.press('ArrowRight')
139
+ await page.waitForTimeout(300)
140
+
141
+ const submenuContent = page.getByTestId('submenu-content')
142
+ await expect(submenuContent).toBeVisible()
143
+
144
+ // focus first item in submenu
145
+ const submenuItem = page.getByTestId('submenu-item-1')
146
+ await expect(submenuItem).toBeFocused()
147
+
148
+ // press ArrowLeft to close submenu and return to parent
149
+ await page.keyboard.press('ArrowLeft')
150
+ await page.waitForTimeout(300)
151
+
152
+ // submenu should be closed
153
+ await expect(submenuContent).not.toBeVisible()
154
+
155
+ // parent menu should still be open
156
+ await expect(menuContent).toBeVisible()
157
+
158
+ // focus should return to submenu trigger WITH focusVisible
159
+ await expect(submenuTrigger).toBeFocused()
160
+
161
+ // check that the submenu trigger has the data-highlighted attribute (focus visible)
162
+ const hasHighlight = await submenuTrigger.getAttribute('data-highlighted')
163
+ expect(hasHighlight).toBe('')
164
+ })
165
+ })
166
+
167
+ test.describe('Menu Submenu Left-Side Keyboard Navigation', () => {
168
+ test.beforeEach(async ({ page }) => {
169
+ await setupPage(page, { name: 'MenuSubLeftCase', type: 'useCase' })
170
+ })
171
+
172
+ test('ArrowRight opens left-side submenu (same as right-side)', async ({ page }) => {
173
+ await page.waitForLoadState('networkidle')
174
+
175
+ // open menu
176
+ const menuTrigger = page.locator('#menu-trigger')
177
+ await menuTrigger.click()
178
+ await page.waitForTimeout(200)
179
+
180
+ const menuContent = page.locator('#menu-content')
181
+ await expect(menuContent).toBeVisible()
182
+
183
+ // focus submenu trigger
184
+ const submenuTrigger = page.locator('#submenu-trigger')
185
+ await submenuTrigger.focus()
186
+ await expect(submenuTrigger).toBeFocused()
187
+
188
+ // ArrowRight should open submenu regardless of placement side
189
+ await page.keyboard.press('ArrowRight')
190
+ await page.waitForTimeout(300)
191
+
192
+ const submenuContent = page.locator('#submenu-content')
193
+ await expect(submenuContent).toBeVisible()
194
+ })
195
+
196
+ test('ArrowLeft closes left-side submenu (same as right-side)', async ({ page }) => {
197
+ await page.waitForLoadState('networkidle')
198
+
199
+ // open menu
200
+ const menuTrigger = page.locator('#menu-trigger')
201
+ await menuTrigger.click()
202
+ await page.waitForTimeout(200)
203
+
204
+ // open submenu via ArrowRight
205
+ const submenuTrigger = page.locator('#submenu-trigger')
206
+ await submenuTrigger.focus()
207
+ await page.keyboard.press('ArrowRight')
208
+ await page.waitForTimeout(300)
209
+
210
+ const submenuContent = page.locator('#submenu-content')
211
+ await expect(submenuContent).toBeVisible()
212
+
213
+ // ArrowLeft should close submenu regardless of placement side
214
+ await page.keyboard.press('ArrowLeft')
215
+ await page.waitForTimeout(300)
216
+
217
+ await expect(submenuContent).not.toBeVisible()
218
+ await expect(submenuTrigger).toBeFocused()
219
+ })
220
+ })
@@ -0,0 +1,88 @@
1
+ import { expect, test } from '@playwright/test'
2
+
3
+ import { setupPage } from './test-utils'
4
+
5
+ test.beforeEach(async ({ page }) => {
6
+ await setupPage(page, { name: 'MenuSubLeftCase', type: 'useCase' })
7
+ })
8
+
9
+ /**
10
+ * Tests for Menu Submenu SafePolygon behavior when submenu opens to the LEFT
11
+ */
12
+
13
+ test('left-side submenu has data-side="left" attribute required for safePolygon', async ({
14
+ page,
15
+ }) => {
16
+ await page.waitForLoadState('networkidle')
17
+
18
+ const menuTrigger = page.locator('#menu-trigger')
19
+ const menuContent = page.locator('#menu-content')
20
+ const submenuTrigger = page.locator('#submenu-trigger')
21
+ const submenuContent = page.locator('#submenu-content')
22
+
23
+ await menuTrigger.click()
24
+ await expect(menuContent).toBeVisible({ timeout: 5000 })
25
+
26
+ await submenuTrigger.hover()
27
+ await page.waitForTimeout(200)
28
+ await expect(submenuContent).toBeVisible({ timeout: 5000 })
29
+
30
+ // data-side tells safePolygon which direction the submenu is
31
+ // for left-side submenus, this should be 'left'
32
+ const dataSide = await submenuContent.getAttribute('data-side')
33
+ expect(dataSide).toBe('left')
34
+ })
35
+
36
+ test('safePolygon keeps left-side submenu open when mouse crosses parent menu items', async ({
37
+ page,
38
+ }) => {
39
+ await page.waitForLoadState('networkidle')
40
+
41
+ const menuTrigger = page.locator('#menu-trigger')
42
+ const menuContent = page.locator('#menu-content')
43
+ const submenuTrigger = page.locator('#submenu-trigger')
44
+ const submenuContent = page.locator('#submenu-content')
45
+
46
+ await menuTrigger.click()
47
+ await expect(menuContent).toBeVisible({ timeout: 5000 })
48
+
49
+ await submenuTrigger.hover()
50
+ await page.waitForTimeout(200)
51
+ await expect(submenuContent).toBeVisible({ timeout: 5000 })
52
+
53
+ // get positions
54
+ const triggerBox = await submenuTrigger.boundingBox()
55
+ const submenuBox = await submenuContent.boundingBox()
56
+
57
+ if (!triggerBox || !submenuBox) {
58
+ throw new Error('Could not get bounding boxes')
59
+ }
60
+
61
+ // start at the submenu trigger
62
+ const startX = triggerBox.x + triggerBox.width / 2
63
+ const startY = triggerBox.y + triggerBox.height / 2
64
+
65
+ // end inside submenu content - moving LEFT and DOWN
66
+ // the submenu is to the LEFT of the trigger
67
+ const endX = submenuBox.x + submenuBox.width / 2
68
+ const endY = submenuBox.y + submenuBox.height - 20
69
+
70
+ await page.mouse.move(startX, startY)
71
+ await page.waitForTimeout(30)
72
+
73
+ // move diagonally DOWN and LEFT
74
+ // this path crosses through menu items below the trigger
75
+ // safePolygon should prevent those items from stealing focus
76
+ const steps = 12
77
+ for (let i = 1; i <= steps; i++) {
78
+ const progress = i / steps
79
+ const x = startX + (endX - startX) * progress
80
+ const y = startY + (endY - startY) * progress
81
+ await page.mouse.move(x, y)
82
+ await page.waitForTimeout(20)
83
+ }
84
+
85
+ // submenu should stay open because safePolygon correctly identifies
86
+ // side='left' from the placement and matches it with pointerDir='left'
87
+ await expect(submenuContent).toBeVisible()
88
+ })
@@ -0,0 +1,48 @@
1
+ import { expect, test } from '@playwright/test'
2
+
3
+ import { setupPage } from './test-utils'
4
+
5
+ test.beforeEach(async ({ page }) => {
6
+ await setupPage(page, { name: 'MenuSubNestedPositionCase', type: 'useCase' })
7
+ })
8
+
9
+ test('nested submenu does not overlap parent submenu', async ({ page }) => {
10
+ await page.setViewportSize({ width: 500, height: 600 })
11
+ await page.waitForLoadState('networkidle')
12
+
13
+ // open root menu
14
+ await page.locator('#menu-trigger').focus()
15
+ await page.keyboard.press('Enter')
16
+ await page.waitForTimeout(400)
17
+ await expect(page.locator('#menu-content')).toBeVisible({ timeout: 5000 })
18
+
19
+ // open sub
20
+ await page.keyboard.press('ArrowDown')
21
+ await page.waitForTimeout(100)
22
+ await page.keyboard.press('ArrowRight')
23
+ await page.waitForTimeout(400)
24
+ await expect(page.locator('#sub-content')).toBeVisible({ timeout: 5000 })
25
+
26
+ // open nested
27
+ await page.keyboard.press('ArrowDown')
28
+ await page.waitForTimeout(100)
29
+ await page.keyboard.press('ArrowRight')
30
+ await page.waitForTimeout(400)
31
+ await expect(page.locator('#nested-content')).toBeVisible({ timeout: 5000 })
32
+
33
+ // nested center must be far from its PARENT sub center (not root)
34
+ const centers = await page.evaluate(() => {
35
+ const rect = (id: string) => {
36
+ const r = document.getElementById(id)!.getBoundingClientRect()
37
+ return { cx: r.x + r.width / 2, cy: r.y + r.height / 2 }
38
+ }
39
+ return { sub: rect('sub-content'), nested: rect('nested-content') }
40
+ })
41
+
42
+ const dx = Math.abs(centers.nested.cx - centers.sub.cx)
43
+ const dy = Math.abs(centers.nested.cy - centers.sub.cy)
44
+ const distance = Math.sqrt(dx * dx + dy * dy)
45
+
46
+ // centers must be far apart - nested should NOT sit on top of parent sub
47
+ expect(distance).toBeGreaterThan(100)
48
+ })
@@ -0,0 +1,97 @@
1
+ import { expect, test } from '@playwright/test'
2
+
3
+ import { setupPage } from './test-utils'
4
+
5
+ test.beforeEach(async ({ page }) => {
6
+ await setupPage(page, { name: 'MenuSubCase', type: 'useCase' })
7
+ })
8
+
9
+ /**
10
+ * Tests for Menu Submenu SafePolygon behavior
11
+ */
12
+
13
+ test('submenu has data-side attribute required for safePolygon', async ({ page }) => {
14
+ await page.waitForLoadState('networkidle')
15
+
16
+ const menuTrigger = page.locator('#menu-trigger')
17
+ const menuContent = page.locator('#menu-content')
18
+ const submenuTrigger = page.locator('#submenu-trigger')
19
+ const submenuContent = page.locator('#submenu-content')
20
+
21
+ await menuTrigger.click()
22
+ await expect(menuContent).toBeVisible({ timeout: 5000 })
23
+
24
+ await submenuTrigger.hover()
25
+ await page.waitForTimeout(200)
26
+ await expect(submenuContent).toBeVisible({ timeout: 5000 })
27
+
28
+ // data-side tells safePolygon which direction the submenu is
29
+ // Without it, isPointerMovingToSubmenu always returns false
30
+ const dataSide = await submenuContent.getAttribute('data-side')
31
+ expect(dataSide).toBe('right')
32
+ })
33
+
34
+ test('safePolygon keeps submenu open when mouse crosses parent menu items', async ({
35
+ page,
36
+ }) => {
37
+ await page.waitForLoadState('networkidle')
38
+
39
+ const menuTrigger = page.locator('#menu-trigger')
40
+ const menuContent = page.locator('#menu-content')
41
+ const submenuTrigger = page.locator('#submenu-trigger')
42
+ const submenuContent = page.locator('#submenu-content')
43
+ const menuItem4 = page.locator('#menu-item-4') // Below the submenu trigger
44
+
45
+ await menuTrigger.click()
46
+ await expect(menuContent).toBeVisible({ timeout: 5000 })
47
+
48
+ await submenuTrigger.hover()
49
+ await page.waitForTimeout(200)
50
+ await expect(submenuContent).toBeVisible({ timeout: 5000 })
51
+
52
+ // Get positions
53
+ const triggerBox = await submenuTrigger.boundingBox()
54
+ const submenuBox = await submenuContent.boundingBox()
55
+ const item4Box = await menuItem4.boundingBox()
56
+
57
+ if (!triggerBox || !submenuBox || !item4Box) {
58
+ throw new Error('Could not get bounding boxes')
59
+ }
60
+
61
+ // Start at the submenu trigger
62
+ const startX = triggerBox.x + triggerBox.width / 2
63
+ const startY = triggerBox.y + triggerBox.height / 2
64
+
65
+ // End inside submenu content - but path goes DOWN through item4's vertical space
66
+ // then RIGHT into the submenu
67
+ const endX = submenuBox.x + submenuBox.width / 2
68
+ const endY = submenuBox.y + submenuBox.height - 20 // Bottom of submenu
69
+
70
+ await page.mouse.move(startX, startY)
71
+ await page.waitForTimeout(30)
72
+
73
+ // Move diagonally DOWN and RIGHT
74
+ // This path crosses through the area where item4 is located horizontally
75
+ // Without safePolygon, hovering over item4 would close the submenu
76
+ const steps = 12
77
+ for (let i = 1; i <= steps; i++) {
78
+ const progress = i / steps
79
+ const x = startX + (endX - startX) * progress
80
+ const y = startY + (endY - startY) * progress
81
+ await page.mouse.move(x, y)
82
+ await page.waitForTimeout(20)
83
+ }
84
+
85
+ // With safePolygon working:
86
+ // - When leaving trigger, polygon is created with side='right'
87
+ // - Mouse moving right matches side='right', so isPointerMovingToSubmenu=true
88
+ // - onItemEnter on item4 calls preventDefault, item4 doesn't steal focus
89
+ // - Submenu stays open
90
+ //
91
+ // Without fix (side=undefined):
92
+ // - isPointerMovingToSubmenu returns false (pointerDir 'right' !== undefined)
93
+ // - onItemEnter doesn't preventDefault
94
+ // - item4 gets focused, triggering onFocusOutside on submenu
95
+ // - Submenu closes
96
+ await expect(submenuContent).toBeVisible()
97
+ })
@@ -0,0 +1,40 @@
1
+ import { expect, test } from '@playwright/test'
2
+
3
+ import { setupPage } from './test-utils'
4
+
5
+ test.beforeEach(async ({ page }) => {
6
+ await setupPage(page, { name: 'MenuSubStyledCase', type: 'useCase' })
7
+ })
8
+
9
+ test('styled(Menu.SubContent) positions submenu correctly', async ({ page }) => {
10
+ await page.waitForLoadState('networkidle')
11
+
12
+ // open the menu
13
+ await page.click('#menu-trigger')
14
+ await page.waitForTimeout(300)
15
+
16
+ // hover on submenu trigger to open submenu
17
+ await page.hover('#submenu-trigger')
18
+ await page.waitForTimeout(500)
19
+
20
+ // check that submenu is visible
21
+ const submenuContent = page.locator('#submenu-content')
22
+ await expect(submenuContent).toBeVisible()
23
+
24
+ // get positions
25
+ const triggerBox = await page.locator('#submenu-trigger').boundingBox()
26
+ const submenuBox = await submenuContent.boundingBox()
27
+
28
+ expect(triggerBox).toBeTruthy()
29
+ expect(submenuBox).toBeTruthy()
30
+
31
+ // submenu should be positioned to the right of the trigger, not at top-left (0,0)
32
+ // the submenu's left edge should be near or to the right of the trigger's right edge
33
+ expect(submenuBox!.x).toBeGreaterThan(triggerBox!.x)
34
+ // the submenu should not be at y=0 (top of viewport)
35
+ expect(submenuBox!.y).toBeGreaterThan(50)
36
+
37
+ // verify submenu has items
38
+ await expect(page.locator('#submenu-item-1')).toBeVisible()
39
+ await expect(page.locator('#submenu-item-2')).toBeVisible()
40
+ })
@@ -0,0 +1,34 @@
1
+ import { expect, test } from '@playwright/test'
2
+ import { setupPage } from './test-utils'
3
+
4
+ test.describe('Menu Theme Inheritance', () => {
5
+ test.beforeEach(async ({ page }) => {
6
+ await setupPage(page, { name: 'MenuThemeCase', type: 'useCase' })
7
+ })
8
+
9
+ test('menu content inherits theme from parent context', async ({ page }) => {
10
+ const trigger = page.getByTestId('menu-trigger')
11
+ await expect(trigger).toBeVisible()
12
+
13
+ await trigger.focus()
14
+ await page.keyboard.press('Enter')
15
+ await page.waitForTimeout(300)
16
+
17
+ const menuContent = page.getByTestId('menu-content')
18
+ await expect(menuContent).toBeVisible()
19
+
20
+ // check that menu content ancestor has the theme class
21
+ const hasThemeClass = await menuContent.evaluate((el) => {
22
+ let current = el.parentElement
23
+ while (current) {
24
+ if (current.className?.includes('t_blue')) {
25
+ return true
26
+ }
27
+ current = current.parentElement
28
+ }
29
+ return false
30
+ })
31
+
32
+ expect(hasThemeClass).toBe(true)
33
+ })
34
+ })
@@ -0,0 +1,56 @@
1
+ import { expect, test } from '@playwright/test'
2
+ import { setupPage } from './test-utils'
3
+
4
+ test.beforeEach(async ({ page }) => {
5
+ await setupPage(page, { name: 'MenuUnstyledCase', type: 'useCase' })
6
+ })
7
+
8
+ test('Menu.Content unstyled removes all default styles', async ({ page }) => {
9
+ // open the unstyled menu
10
+ await page.getByTestId('unstyled-menu-trigger').click()
11
+ await page.waitForTimeout(300)
12
+
13
+ const unstyledContent = page.getByTestId('unstyled-menu-content')
14
+ await expect(unstyledContent).toBeVisible()
15
+
16
+ // check that unstyled menu has no background/padding/border from defaults
17
+ const unstyledStyles = await unstyledContent.evaluate((el) => {
18
+ const computed = window.getComputedStyle(el)
19
+ return {
20
+ backgroundColor: computed.backgroundColor,
21
+ padding: computed.padding,
22
+ borderWidth: computed.borderWidth,
23
+ }
24
+ })
25
+
26
+ // unstyled should have transparent/none background (rgba(0,0,0,0) or transparent)
27
+ expect(
28
+ unstyledStyles.backgroundColor === 'rgba(0, 0, 0, 0)' ||
29
+ unstyledStyles.backgroundColor === 'transparent'
30
+ ).toBe(true)
31
+
32
+ // close the unstyled menu
33
+ await page.keyboard.press('Escape')
34
+ await page.waitForTimeout(200)
35
+
36
+ // open the styled menu (default)
37
+ await page.getByTestId('styled-menu-trigger').click()
38
+ await page.waitForTimeout(300)
39
+
40
+ const styledContent = page.getByTestId('styled-menu-content')
41
+ await expect(styledContent).toBeVisible()
42
+
43
+ // check that styled menu has background applied
44
+ const styledStyles = await styledContent.evaluate((el) => {
45
+ const computed = window.getComputedStyle(el)
46
+ return {
47
+ backgroundColor: computed.backgroundColor,
48
+ }
49
+ })
50
+
51
+ // styled should have a real background color (not transparent)
52
+ expect(
53
+ styledStyles.backgroundColor !== 'rgba(0, 0, 0, 0)' &&
54
+ styledStyles.backgroundColor !== 'transparent'
55
+ ).toBe(true)
56
+ })