@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.
- package/.detoxrc.js +130 -0
- package/.env.production +2 -0
- package/.maestro/config.yaml +4 -0
- package/.maestro/flows/shorthand-variables.yaml +23 -0
- package/.watchmanconfig +1 -0
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/app.json +43 -0
- package/assets/adaptive-icon.png +0 -0
- package/assets/favicon.png +0 -0
- package/assets/icon.png +0 -0
- package/assets/splash.png +0 -0
- package/babel.config.js +25 -0
- package/e2e/CompilerExtraction.test.ts +147 -0
- package/e2e/GroupPressNative.test.ts +167 -0
- package/e2e/MediaQueryGtMd.test.ts +71 -0
- package/e2e/NativePortal.test.ts +113 -0
- package/e2e/PointerEvents.test.ts +116 -0
- package/e2e/PressStyleNative.noRngh.test.ts +191 -0
- package/e2e/PressStyleNative.test.ts +231 -0
- package/e2e/SafeArea.test.ts +57 -0
- package/e2e/SelectAndroidOnPress.test.ts +181 -0
- package/e2e/SelectRemount.test.ts +137 -0
- package/e2e/SheetDragResist.test.ts +370 -0
- package/e2e/SheetKeyboardDrag.test.ts +249 -0
- package/e2e/SheetScrollableDrag.test.ts +560 -0
- package/e2e/ShorthandVariables.test.ts +53 -0
- package/e2e/ThemeChangeBasic.test.ts +123 -0
- package/e2e/ThemeMutation.test.ts +80 -0
- package/e2e/check-rngh-status.test.ts +31 -0
- package/e2e/jest.config.js +19 -0
- package/e2e/utils/colors.ts +75 -0
- package/e2e/utils/navigation.ts +53 -0
- package/eas.json +22 -0
- package/flows/AlertDialog.yaml +17 -0
- package/flows/OpenApp.yaml +25 -0
- package/flows/Select.yaml +13 -0
- package/flows/Sheet.yaml +12 -0
- package/flows/Tabs.yaml +13 -0
- package/flows/Toast.yaml +14 -0
- package/flows/WarmUp.yaml +24 -0
- package/index.html +21 -0
- package/index.js +17 -0
- package/metro.config.js +64 -0
- package/next-router-shim.ts +9 -0
- package/package.json +118 -0
- package/plans/toast-2.md +471 -0
- package/playwright.config.ts +71 -0
- package/plugins/expo-modules-core-swift6.js +76 -0
- package/pod-install.sh +7 -0
- package/public/favicon.svg +70 -0
- package/public/fonts/inter.css +15 -0
- package/public/fonts/noto-cn.otf +0 -0
- package/public/gui-icon.svg +68 -0
- package/run-detox.sh +230 -0
- package/run-native-tests.sh +4 -0
- package/run-tests-parallel.ts +195 -0
- package/screenshots/Screenshotter.test.tsx +48 -0
- package/src/AnimationDemos.tsx +131 -0
- package/src/App.native.tsx +121 -0
- package/src/App.tsx +121 -0
- package/src/Navigation.tsx +98 -0
- package/src/Sandbox.tsx +87 -0
- package/src/TestDynamicEval.tsx +33 -0
- package/src/TestNativeSheet.tsx +100 -0
- package/src/components/TimedRender.tsx +18 -0
- package/src/constants/test-ids.ts +52 -0
- package/src/features/demos/demo-screen.tsx +72 -0
- package/src/features/home/ColorSchemeListItem.tsx +41 -0
- package/src/features/home/TestBuildAButton.tsx +102 -0
- package/src/features/home/TestSeparator.tsx +0 -0
- package/src/features/home/screen.tsx +285 -0
- package/src/features/testcases/screen.tsx +59 -0
- package/src/features/testcases/test-screen.tsx +50 -0
- package/src/generatedV5Theme.ts +112 -0
- package/src/gui.config.ts +411 -0
- package/src/guy.png +0 -0
- package/src/index.tsx +6 -0
- package/src/provider/index.tsx +18 -0
- package/src/test-gui-stack.tsx +11 -0
- package/src/test.tsx +3 -0
- package/src/useKitchenSinkTheme.tsx +15 -0
- package/src/usecases/ActionsSheetComparison.tsx +194 -0
- package/src/usecases/AnimatePresenceEnterExitCase.tsx +255 -0
- package/src/usecases/AnimatePresenceExitTest.tsx +69 -0
- package/src/usecases/AnimatedByProp.tsx +39 -0
- package/src/usecases/AnimationComprehensiveCase.tsx +2515 -0
- package/src/usecases/AnimationValueLoggingCase.tsx +526 -0
- package/src/usecases/AnimationsWithMediaQueriesCase.tsx +110 -0
- package/src/usecases/Benchmark.tsx +148 -0
- package/src/usecases/BenchmarkSelect.tsx +34 -0
- package/src/usecases/ButtonCircular.tsx +3 -0
- package/src/usecases/ButtonCustom.tsx +33 -0
- package/src/usecases/ButtonIconColor.tsx +18 -0
- package/src/usecases/ButtonInverse.tsx +30 -0
- package/src/usecases/ButtonUnstyled.tsx +31 -0
- package/src/usecases/CheckboxDisabledOnPress.tsx +62 -0
- package/src/usecases/ClickDuringEnterCase.tsx +59 -0
- package/src/usecases/CodeExamplesInput.tsx +9 -0
- package/src/usecases/ColorTokenFallback.tsx +52 -0
- package/src/usecases/CompilerExtraction.tsx +380 -0
- package/src/usecases/ComplexVariants.tsx +164 -0
- package/src/usecases/CrashAdaptSheet.tsx +98 -0
- package/src/usecases/CustomStyledAnimatedPopover.tsx +42 -0
- package/src/usecases/CustomStyledAnimatedTooltip.tsx +72 -0
- package/src/usecases/DOMNodeAPIs.tsx +154 -0
- package/src/usecases/DialogFocusScopeCase.tsx +277 -0
- package/src/usecases/DialogFocusScopeDebug.tsx +85 -0
- package/src/usecases/DialogNestedCase.tsx +121 -0
- package/src/usecases/DialogOpenControlled.tsx +49 -0
- package/src/usecases/DialogPointerEventsCase.tsx +58 -0
- package/src/usecases/DialogScopedCase.tsx +106 -0
- package/src/usecases/DialogSheetAdaptCase.tsx +178 -0
- package/src/usecases/DialogSheetAdaptResizeCase.tsx +98 -0
- package/src/usecases/DismissLayerStackingCase.tsx +223 -0
- package/src/usecases/DriverDisableAnimationPropsCase.tsx +44 -0
- package/src/usecases/Example.tsx +10 -0
- package/src/usecases/ExitCompletionCase.tsx +713 -0
- package/src/usecases/FocusVisibleButton.tsx +14 -0
- package/src/usecases/FocusVisibleButtonPointer.tsx +13 -0
- package/src/usecases/FocusVisibleButtonWithFocusStyle.tsx +16 -0
- package/src/usecases/FocusWithinCase.tsx +55 -0
- package/src/usecases/FontTokensInVariants.tsx +14 -0
- package/src/usecases/FormButtonTypeCase.tsx +34 -0
- package/src/usecases/GlobalScopedTriggerIsolationCase.tsx +178 -0
- package/src/usecases/GroupHoverMobile.tsx +39 -0
- package/src/usecases/GroupPressInVariant.tsx +92 -0
- package/src/usecases/GroupPressNative.tsx +200 -0
- package/src/usecases/GroupProp.tsx +96 -0
- package/src/usecases/GroupPseudoVariantOverride.tsx +56 -0
- package/src/usecases/GroupUseCases.tsx +94 -0
- package/src/usecases/HeightMediaQueryOverrideCase.tsx +183 -0
- package/src/usecases/InputAutoFocusAfterMenuCase.tsx +105 -0
- package/src/usecases/InputAutoFocusStyledCase.tsx +39 -0
- package/src/usecases/KeyboardControllerTest.tsx +146 -0
- package/src/usecases/ListItem.tsx +123 -0
- package/src/usecases/MediaQueriesV5.tsx +137 -0
- package/src/usecases/MediaQueryGtMd.tsx +73 -0
- package/src/usecases/MenuAboveDialogCase.tsx +75 -0
- package/src/usecases/MenuAccessibilityCase.tsx +133 -0
- package/src/usecases/MenuAnimatePositionCase.tsx +41 -0
- package/src/usecases/MenuArrowAnimatePresenceCase.tsx +98 -0
- package/src/usecases/MenuAsChildPositionCase.tsx +24 -0
- package/src/usecases/MenuAutoResizeCase.tsx +57 -0
- package/src/usecases/MenuBottomCase.tsx +55 -0
- package/src/usecases/MenuFocusLeaveCase.tsx +135 -0
- package/src/usecases/MenuHighlightCase.tsx +44 -0
- package/src/usecases/MenuItemFocusCase.tsx +79 -0
- package/src/usecases/MenuItemPseudoOverrideCase.tsx +270 -0
- package/src/usecases/MenuMultiTriggerCase.tsx +47 -0
- package/src/usecases/MenuOverflowCase.tsx +60 -0
- package/src/usecases/MenuSubCase.tsx +223 -0
- package/src/usecases/MenuSubLeftCase.tsx +178 -0
- package/src/usecases/MenuSubNestedPositionCase.tsx +171 -0
- package/src/usecases/MenuSubStyledCase.tsx +145 -0
- package/src/usecases/MenuThemeCase.tsx +50 -0
- package/src/usecases/MenuUnstyledCase.tsx +52 -0
- package/src/usecases/MultiDriverAnimation.tsx +118 -0
- package/src/usecases/NativePortalTest.tsx +179 -0
- package/src/usecases/NewInputBasic.tsx +16 -0
- package/src/usecases/NewInputEvents.tsx +29 -0
- package/src/usecases/NonGuiTextStyledType.tsx +23 -0
- package/src/usecases/OnLayoutCase.tsx +134 -0
- package/src/usecases/OnLayoutScaleCase.tsx +88 -0
- package/src/usecases/OnLayoutStressCase.tsx +353 -0
- package/src/usecases/OpacityModifierCase.tsx +113 -0
- package/src/usecases/OverlayStyled.tsx +66 -0
- package/src/usecases/ParagraphSpanFontInheritance.tsx +53 -0
- package/src/usecases/PlaceholderTextColor.tsx +20 -0
- package/src/usecases/PointerEventsCase.tsx +100 -0
- package/src/usecases/PopoverAndMenuMultiTriggerCase.tsx +138 -0
- package/src/usecases/PopoverCase.tsx +222 -0
- package/src/usecases/PopoverContentStyledPlusAnimations.tsx +44 -0
- package/src/usecases/PopoverFocusScopeCase.tsx +171 -0
- package/src/usecases/PopoverHoverableCase.tsx +167 -0
- package/src/usecases/PopoverHoverableDisableClickCase.tsx +118 -0
- package/src/usecases/PopoverHoverableRapidCase.tsx +103 -0
- package/src/usecases/PopoverHoverableScopedCase.tsx +135 -0
- package/src/usecases/PopoverScopedCase.tsx +76 -0
- package/src/usecases/PopoverTriggerIsolationCase.tsx +80 -0
- package/src/usecases/PressStyleNative.tsx +143 -0
- package/src/usecases/PseudoStyleMerge.tsx +25 -0
- package/src/usecases/PseudoTransitionCase.tsx +174 -0
- package/src/usecases/RawAnimatedValueCase.tsx +231 -0
- package/src/usecases/RemoveScrollCase.tsx +66 -0
- package/src/usecases/RenderPropCase.tsx +263 -0
- package/src/usecases/SafeAreaCase.tsx +236 -0
- package/src/usecases/ScrollViewRefCase.tsx +88 -0
- package/src/usecases/SecondPage.tsx +5 -0
- package/src/usecases/SelectAndroidOnPress.tsx +129 -0
- package/src/usecases/SelectFocusScopeCase.tsx +270 -0
- package/src/usecases/SelectRemount.tsx +136 -0
- package/src/usecases/Shadows.tsx +5 -0
- package/src/usecases/SheetAnimationCase.tsx +155 -0
- package/src/usecases/SheetDragCase.tsx +183 -0
- package/src/usecases/SheetDragResistCase.tsx +433 -0
- package/src/usecases/SheetDragResistCase.web.tsx +359 -0
- package/src/usecases/SheetKeyboardDragCase.tsx +328 -0
- package/src/usecases/SheetKeyboardFitContentCase.tsx +165 -0
- package/src/usecases/SheetOnAnimationCompleteCase.tsx +54 -0
- package/src/usecases/SheetScrollLockCase.tsx +166 -0
- package/src/usecases/SheetScrollableDrag.tsx +249 -0
- package/src/usecases/SheetSnapPointsFitCase.tsx +393 -0
- package/src/usecases/ShorthandVariables.tsx +49 -0
- package/src/usecases/SlowThemeReRender.tsx +48 -0
- package/src/usecases/SpinnerCustomColors.tsx +34 -0
- package/src/usecases/StackZIndex.tsx +82 -0
- package/src/usecases/StressPage.tsx +301 -0
- package/src/usecases/StylePlatform.tsx +30 -0
- package/src/usecases/StyleProp.tsx +29 -0
- package/src/usecases/StyledAnchor.tsx +27 -0
- package/src/usecases/StyledButtonAnimationAuto.tsx +99 -0
- package/src/usecases/StyledButtonTheme.tsx +63 -0
- package/src/usecases/StyledButtonVariantPseudo.tsx +25 -0
- package/src/usecases/StyledButtonVariantPseudoMerge.tsx +77 -0
- package/src/usecases/StyledCheckboxTheme.tsx +23 -0
- package/src/usecases/StyledContextColor.tsx +246 -0
- package/src/usecases/StyledContextTokens.tsx +147 -0
- package/src/usecases/StyledHOCNamed.tsx +20 -0
- package/src/usecases/StyledHtmlCase.tsx +144 -0
- package/src/usecases/StyledIconColor.tsx +19 -0
- package/src/usecases/StyledInputFocusStyle.tsx +21 -0
- package/src/usecases/StyledInputOnFocus.tsx +30 -0
- package/src/usecases/StyledMediaQueryMerge.tsx +95 -0
- package/src/usecases/StyledOverridePsuedo.tsx +26 -0
- package/src/usecases/StyledRNW.tsx +61 -0
- package/src/usecases/StyledStyleableInputOnFocus.tsx +34 -0
- package/src/usecases/StyledStyleableInputVariant.tsx +48 -0
- package/src/usecases/StyledStyledStyleableInputOnFocus.tsx +36 -0
- package/src/usecases/StyledVariantTextColor.tsx +25 -0
- package/src/usecases/StyledViewOnFocus.tsx +32 -0
- package/src/usecases/TabHoverAnimationCase.tsx +212 -0
- package/src/usecases/TextNestedInheritance.tsx +80 -0
- package/src/usecases/ThemeChange.tsx +100 -0
- package/src/usecases/ThemeChangeBasic.tsx +52 -0
- package/src/usecases/ThemeComponentResolution.tsx +119 -0
- package/src/usecases/ThemeConditionalName.tsx +31 -0
- package/src/usecases/ThemeMediaAnimationCase.tsx +39 -0
- package/src/usecases/ThemeMutation.tsx +86 -0
- package/src/usecases/ThemeNested.tsx +103 -0
- package/src/usecases/ThemeReset.tsx +62 -0
- package/src/usecases/ThemeShallowCase.tsx +83 -0
- package/src/usecases/ToastCase.tsx +46 -0
- package/src/usecases/ToggleGroupActiveProps.tsx +40 -0
- package/src/usecases/ToggleGroupXGroupCase.tsx +104 -0
- package/src/usecases/TooltipAnimationCase.tsx +99 -0
- package/src/usecases/TooltipCase.tsx +32 -0
- package/src/usecases/TooltipGlobalPatternCase.tsx +83 -0
- package/src/usecases/TooltipGroupCase.tsx +102 -0
- package/src/usecases/TooltipMultiTriggerCase.tsx +88 -0
- package/src/usecases/TooltipPositionJumpCase.tsx +91 -0
- package/src/usecases/TooltipTriggerInlineCase.tsx +60 -0
- package/src/usecases/TransformMediaQueryMerge.tsx +98 -0
- package/src/usecases/UseCases.tsx +409 -0
- package/src/usecases/UseTheme.tsx +41 -0
- package/src/usecases/V5ThemeBuilderOutput.tsx +231 -0
- package/src/usecases/VariantFontFamily.tsx +25 -0
- package/src/usecases/VariantsOrder.tsx +117 -0
- package/src/usecases/ZIndex.tsx +155 -0
- package/src/usecases/helpers.tsx +44 -0
- package/src/usecases/index.native.ts +122 -0
- package/src/usecases/index.ts +3 -0
- package/src/usecases/index.web.ts +177 -0
- package/tests/AnimatePresenceEnterExit.animated.test.tsx +176 -0
- package/tests/AnimatedByProp.animated.test.tsx +138 -0
- package/tests/AnimationBehavior.animated.test.tsx +543 -0
- package/tests/AnimationTiming.animated.test.tsx +195 -0
- package/tests/AnimationsWithMediaQueries.animated.test.tsx +154 -0
- package/tests/BuildAButton.test.tsx +87 -0
- package/tests/ButtonCircular.test.tsx +17 -0
- package/tests/ButtonCustom.test.tsx +17 -0
- package/tests/ButtonIconColor.test.tsx +23 -0
- package/tests/ButtonUnstyled.test.tsx +56 -0
- package/tests/ClickDuringEnter.animated.test.tsx +174 -0
- package/tests/ColorTokenFallback.test.tsx +45 -0
- package/tests/DOMNodeAPIs.test.tsx +161 -0
- package/tests/DialogFocusScope.animated.test.tsx +309 -0
- package/tests/DialogNested.test.tsx +128 -0
- package/tests/DialogOpenControlled.test.tsx +42 -0
- package/tests/DialogPointerEvents.animated.test.tsx +108 -0
- package/tests/DialogScoped.test.tsx +137 -0
- package/tests/DialogSheetAdapt.test.tsx +68 -0
- package/tests/DialogSheetAdaptResize.test.tsx +161 -0
- package/tests/DismissLayerStacking.test.tsx +292 -0
- package/tests/DriverDisableAnimationProps.animated.test.tsx +157 -0
- package/tests/ExitCompletion.animated.test.tsx +425 -0
- package/tests/ExitTimingCheck.animated.test.ts +34 -0
- package/tests/FocusVisibleButton.test.tsx +41 -0
- package/tests/FocusVisibleButtonPointerFocus.test.tsx +23 -0
- package/tests/FocusVisibleButtonPointerFocusWithFocusStyle.test.tsx +40 -0
- package/tests/FocusWithinStyle.animated.test.tsx +66 -0
- package/tests/FocusWithinStyle.test.tsx +60 -0
- package/tests/FormButtonType.test.tsx +42 -0
- package/tests/GlobalScopedTriggerIsolation.test.tsx +89 -0
- package/tests/GroupHoverMobile.test.tsx +52 -0
- package/tests/GroupPressInVariant.test.tsx +82 -0
- package/tests/GroupProp.test.tsx +30 -0
- package/tests/GroupPseudoVariantOverride.test.tsx +57 -0
- package/tests/GroupUseCases.test.tsx +111 -0
- package/tests/GuiSiteMotion.test.ts +481 -0
- package/tests/HeightMediaQueryOverride.test.tsx +112 -0
- package/tests/InputAutoFocusAfterMenu.test.tsx +55 -0
- package/tests/InputAutoFocusStyled.test.tsx +22 -0
- package/tests/ListItem.test.tsx +129 -0
- package/tests/MediaQueriesV5.test.tsx +113 -0
- package/tests/MediaQueryGtMd.test.tsx +84 -0
- package/tests/MenuAboveDialog.test.tsx +108 -0
- package/tests/MenuAccessibility.test.tsx +346 -0
- package/tests/MenuAnimatePosition.animated.test.tsx +57 -0
- package/tests/MenuArrowAnimatePresence.animated.test.tsx +71 -0
- package/tests/MenuAsChildPosition.test.tsx +16 -0
- package/tests/MenuAutoResize.test.tsx +54 -0
- package/tests/MenuFocusLeave.test.tsx +181 -0
- package/tests/MenuHighlight.test.tsx +165 -0
- package/tests/MenuHoverKeyboardBugs.test.tsx +252 -0
- package/tests/MenuItemFocus.test.tsx +59 -0
- package/tests/MenuItemPseudoOverride.test.tsx +231 -0
- package/tests/MenuMultiTrigger.test.tsx +101 -0
- package/tests/MenuOverflow.test.tsx +93 -0
- package/tests/MenuStayInFrame.test.tsx +102 -0
- package/tests/MenuSubKeyboardFocus.test.tsx +220 -0
- package/tests/MenuSubLeftSafePolygon.test.tsx +88 -0
- package/tests/MenuSubNestedPosition.test.tsx +48 -0
- package/tests/MenuSubSafePolygon.test.tsx +97 -0
- package/tests/MenuSubStyled.test.tsx +40 -0
- package/tests/MenuTheme.test.tsx +34 -0
- package/tests/MenuUnstyled.test.tsx +56 -0
- package/tests/MultiDriverAnimation.test.tsx +207 -0
- package/tests/NewInputBasic.test.tsx +50 -0
- package/tests/NewInputEvents.test.tsx +55 -0
- package/tests/OnLayout.test.tsx +163 -0
- package/tests/OnLayoutScale.test.tsx +100 -0
- package/tests/OnLayoutStress.test.tsx +304 -0
- package/tests/ParagraphSpanFontInheritance.test.tsx +73 -0
- package/tests/PointerEvents.test.tsx +123 -0
- package/tests/Popover.animated.test.tsx +234 -0
- package/tests/PopoverAndMenuMultiTrigger.test.tsx +184 -0
- package/tests/PopoverAnimatePosition.animated.test.tsx +51 -0
- package/tests/PopoverClickDuringEnter.animated.test.tsx +197 -0
- package/tests/PopoverFocusScope.test.tsx +242 -0
- package/tests/PopoverHoverable.test.tsx +383 -0
- package/tests/PopoverHoverableDisableClick.test.tsx +106 -0
- package/tests/PopoverHoverableRapid.test.tsx +129 -0
- package/tests/PopoverHoverableReposition.test.tsx +111 -0
- package/tests/PopoverHoverableScoped.animated.test.tsx +103 -0
- package/tests/PopoverHoverableStress.test.tsx +169 -0
- package/tests/PopoverInitialPosition.animated.test.tsx +82 -0
- package/tests/PopoverMiddlewareSkipRegression.animated.test.tsx +221 -0
- package/tests/PopoverScoped.test.tsx +128 -0
- package/tests/PopoverScopedPositionGlitch.animated.test.tsx +184 -0
- package/tests/PopoverTriggerIsolation.test.tsx +62 -0
- package/tests/PseudoTransition.animated.test.tsx +319 -0
- package/tests/RawAnimatedValue.test.tsx +147 -0
- package/tests/RemoveScroll.test.tsx +223 -0
- package/tests/RenderProp.test.tsx +293 -0
- package/tests/ScrollViewRef.test.tsx +39 -0
- package/tests/SelectClickHold.test.tsx +147 -0
- package/tests/SelectFocusScope.test.tsx +176 -0
- package/tests/SelectInnerPositioning.test.tsx +82 -0
- package/tests/SelectKeyboardNav.test.tsx +173 -0
- package/tests/SelectPositioning.test.tsx +56 -0
- package/tests/SelectTypeahead.test.tsx +63 -0
- package/tests/Shadows.test.tsx +14 -0
- package/tests/SheetAnimation.animated.test.tsx +413 -0
- package/tests/SheetDrag.animated.test.tsx +223 -0
- package/tests/SheetDragResist.animated.test.tsx +393 -0
- package/tests/SheetOnAnimationComplete.animated.test.tsx +62 -0
- package/tests/SheetScrollLock.animated.test.tsx +287 -0
- package/tests/SheetScrollableDrag.animated.test.tsx +1264 -0
- package/tests/SheetSnapPointsFit.animated.test.tsx +259 -0
- package/tests/ShorthandVariables.test.tsx +44 -0
- package/tests/SpinnerCustomColors.test.tsx +67 -0
- package/tests/StackZIndex.test.tsx +51 -0
- package/tests/StressPagePerf.test.tsx +76 -0
- package/tests/StylePlatform.test.tsx +38 -0
- package/tests/StyleProp.test.tsx +20 -0
- package/tests/StyledAnchor.test.tsx +17 -0
- package/tests/StyledButtonTheme.test.tsx +22 -0
- package/tests/StyledButtonVariantPseudo.test.tsx +20 -0
- package/tests/StyledButtonVariantPseudoMerge.animated.test.tsx +33 -0
- package/tests/StyledCheckboxTheme.test.tsx +16 -0
- package/tests/StyledContextColor.test.tsx +119 -0
- package/tests/StyledContextTokens.test.tsx +56 -0
- package/tests/StyledHOCNamed.test.tsx +16 -0
- package/tests/StyledHtml.test.tsx +161 -0
- package/tests/StyledIconColor.test.tsx +32 -0
- package/tests/StyledInputFocusStyle.test.tsx +19 -0
- package/tests/StyledInputOnFocus.test.tsx +27 -0
- package/tests/StyledMediaQueryMerge.test.tsx +66 -0
- package/tests/StyledRNW.test.tsx +17 -0
- package/tests/StyledStyleableInputOnFocus.test.tsx +27 -0
- package/tests/StyledStyleableInputVariant.test.tsx +22 -0
- package/tests/StyledStyledStyleableInputOnFocus.test.tsx +27 -0
- package/tests/StyledVariantTextColor.test.tsx +24 -0
- package/tests/StyledViewOnFocus.test.tsx +27 -0
- package/tests/TabHoverAnimation.animated.test.tsx +468 -0
- package/tests/TabHoverPositionSmooth.animated.test.tsx +129 -0
- package/tests/TextNestedInheritance.test.tsx +93 -0
- package/tests/ThemeChange.test.tsx +70 -0
- package/tests/ThemeComponentResolution.test.tsx +82 -0
- package/tests/ThemeConditionalName.test.tsx +34 -0
- package/tests/ThemeMediaAnimation.test.tsx +65 -0
- package/tests/ThemeNested.test.tsx +141 -0
- package/tests/ThemeReset.test.tsx +63 -0
- package/tests/ThemeShallow.test.tsx +95 -0
- package/tests/Toast.test.tsx +106 -0
- package/tests/ToggleGroup.test.tsx +61 -0
- package/tests/ToggleGroupActiveProps.test.tsx +38 -0
- package/tests/ToggleGroupXGroup.test.tsx +172 -0
- package/tests/TooltipAnimation.animated.test.tsx +260 -0
- package/tests/TooltipEnterInterrupt.animated.test.tsx +76 -0
- package/tests/TooltipGlobalPattern.animated.test.tsx +208 -0
- package/tests/TooltipGroup.animated.test.tsx +79 -0
- package/tests/TooltipMultiTrigger.test.tsx +116 -0
- package/tests/TooltipPositionJump.animated.test.tsx +229 -0
- package/tests/TooltipPositionJumpNotes.md +219 -0
- package/tests/TooltipRapidSwitch.animated.test.tsx +399 -0
- package/tests/TooltipTriggerInline.test.tsx +65 -0
- package/tests/TransformMediaQueryMerge.test.tsx +104 -0
- package/tests/TransitionEnterExit.animated.test.tsx +311 -0
- package/tests/UseTheme.test.tsx +16 -0
- package/tests/V5ThemeBuilderOutput.test.tsx +164 -0
- package/tests/VariantFontFamily.test.tsx +11 -0
- package/tests/VariantsOrder.test.tsx +53 -0
- package/tests/_debug_position.mjs +52 -0
- package/tests/test-utils.ts +106 -0
- package/tests/utils.tsx +54 -0
- package/tsconfig.json +45 -0
- package/vite-env.d.ts +1 -0
- package/vite.config.ts +14 -0
- package/webpack.config.js +139 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { expect, test, type Page } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
// layout poll interval is ~233ms (14 frames)
|
|
5
|
+
const POLL_WAIT = 500
|
|
6
|
+
// CI environments are slower - give more time for layouts to settle
|
|
7
|
+
const INITIAL_SETTLE_TIME = process.env.CI ? 3000 : 1500
|
|
8
|
+
|
|
9
|
+
// gating thresholds - fail if exceeded
|
|
10
|
+
const MAX_IO_DELAY_MS = 100 // fail if IO callback takes > 100ms
|
|
11
|
+
const MAX_WARNINGS_PER_TEST = 3 // fail if too many warnings
|
|
12
|
+
|
|
13
|
+
async function collectConsoleWarnings(
|
|
14
|
+
page: Page
|
|
15
|
+
): Promise<{ count: number; avgDelay: number; maxDelay: number }> {
|
|
16
|
+
const result = await page.evaluate(() => {
|
|
17
|
+
const warnings = (window as any).__ioDelayWarnings || []
|
|
18
|
+
if (warnings.length === 0) return { count: 0, avgDelay: 0, maxDelay: 0 }
|
|
19
|
+
const sum = warnings.reduce((a: number, b: number) => a + b, 0)
|
|
20
|
+
const max = Math.max(...warnings)
|
|
21
|
+
return {
|
|
22
|
+
count: warnings.length,
|
|
23
|
+
avgDelay: Math.round(sum / warnings.length),
|
|
24
|
+
maxDelay: max,
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
return result
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function getStats(
|
|
31
|
+
page: Page
|
|
32
|
+
): Promise<{ total: number; lastBatch: number; lastTime: number; max: number }> {
|
|
33
|
+
const total = await page.getByTestId('stat-total').innerText()
|
|
34
|
+
const lastBatch = await page.getByTestId('stat-last-batch').innerText()
|
|
35
|
+
const lastTime = await page.getByTestId('stat-last-time').innerText()
|
|
36
|
+
const max = await page.getByTestId('stat-max').innerText()
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
total: parseInt(total.replace('total: ', ''), 10) || 0,
|
|
40
|
+
lastBatch: parseInt(lastBatch.replace('lastBatch: ', ''), 10) || 0,
|
|
41
|
+
lastTime: parseInt(lastTime.replace('lastTime: ', ''), 10) || 0,
|
|
42
|
+
max: parseInt(max.replace('max: ', '').replace('ms', ''), 10) || 0,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
test.describe('onLayout stress test', () => {
|
|
47
|
+
// stress tests are flaky in CI - give them extra retries
|
|
48
|
+
test.describe.configure({ retries: 3 })
|
|
49
|
+
|
|
50
|
+
test.beforeEach(async ({ page }) => {
|
|
51
|
+
// set up console warning tracking
|
|
52
|
+
// BUG FIX: console.warn('[onLayout-io-delay]', delay + 'ms', ...) puts delay in args[1]
|
|
53
|
+
await page.addInitScript(() => {
|
|
54
|
+
;(window as any).__ioDelayWarnings = []
|
|
55
|
+
const originalWarn = console.warn
|
|
56
|
+
console.warn = (...args: any[]) => {
|
|
57
|
+
const prefix = args[0]
|
|
58
|
+
const delayArg = args[1] // delay is in second argument
|
|
59
|
+
if (typeof prefix === 'string' && prefix.includes('[onLayout-io-delay]')) {
|
|
60
|
+
if (typeof delayArg === 'string') {
|
|
61
|
+
const match = delayArg.match(/(\d+)ms/)
|
|
62
|
+
if (match) {
|
|
63
|
+
;(window as any).__ioDelayWarnings.push(parseInt(match[1], 10))
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
originalWarn.apply(console, args)
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
await setupPage(page, { name: 'OnLayoutStressCase', type: 'useCase' })
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
test('initial render should not exceed threshold', async ({ page }) => {
|
|
75
|
+
// wait for initial layout callbacks to settle
|
|
76
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
77
|
+
|
|
78
|
+
const stats = await getStats(page)
|
|
79
|
+
const warnings = await collectConsoleWarnings(page)
|
|
80
|
+
|
|
81
|
+
console.log('=== INITIAL RENDER BENCHMARK ===')
|
|
82
|
+
console.log(`total callbacks: ${stats.total}`)
|
|
83
|
+
console.log(`last batch size: ${stats.lastBatch}`)
|
|
84
|
+
console.log(`max batch time: ${stats.max}ms`)
|
|
85
|
+
console.log(`IO delay warnings: ${warnings.count}`)
|
|
86
|
+
if (warnings.count > 0) {
|
|
87
|
+
console.log(`avg IO delay: ${warnings.avgDelay}ms`)
|
|
88
|
+
console.log(`max IO delay: ${warnings.maxDelay}ms`)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// gating assertions
|
|
92
|
+
expect(stats.total, 'should have onLayout callbacks').toBeGreaterThan(50)
|
|
93
|
+
expect(warnings.maxDelay, `IO delay should be < ${MAX_IO_DELAY_MS}ms`).toBeLessThan(
|
|
94
|
+
MAX_IO_DELAY_MS
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('resize should trigger batch updates efficiently', async ({ page }) => {
|
|
99
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
100
|
+
|
|
101
|
+
// scroll sibling section into view — onLayout only fires for visible elements
|
|
102
|
+
await page.getByTestId('section-siblings').scrollIntoViewIfNeeded()
|
|
103
|
+
await page.waitForTimeout(POLL_WAIT)
|
|
104
|
+
|
|
105
|
+
// reset stats after initial render
|
|
106
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
107
|
+
await page.waitForTimeout(200)
|
|
108
|
+
|
|
109
|
+
// trigger width resize
|
|
110
|
+
await page.getByTestId('btn-resize-width').click()
|
|
111
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
112
|
+
|
|
113
|
+
const stats = await getStats(page)
|
|
114
|
+
const warnings = await collectConsoleWarnings(page)
|
|
115
|
+
|
|
116
|
+
console.log('=== WIDTH RESIZE BENCHMARK ===')
|
|
117
|
+
console.log(`callbacks after resize: ${stats.total}`)
|
|
118
|
+
console.log(`last batch size: ${stats.lastBatch}`)
|
|
119
|
+
console.log(`last batch time: ${stats.lastTime}ms`)
|
|
120
|
+
console.log(`IO delay warnings: ${warnings.count}`)
|
|
121
|
+
|
|
122
|
+
// gating assertions
|
|
123
|
+
expect(stats.total, 'resize should trigger callbacks').toBeGreaterThan(0)
|
|
124
|
+
expect(
|
|
125
|
+
warnings.count,
|
|
126
|
+
`should have fewer than ${MAX_WARNINGS_PER_TEST} warnings`
|
|
127
|
+
).toBeLessThan(MAX_WARNINGS_PER_TEST)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('grid resize should trigger efficient updates', async ({ page }) => {
|
|
131
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
132
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
133
|
+
await page.waitForTimeout(100)
|
|
134
|
+
|
|
135
|
+
await page.getByTestId('btn-resize-grid').click()
|
|
136
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
137
|
+
|
|
138
|
+
const stats = await getStats(page)
|
|
139
|
+
const warnings = await collectConsoleWarnings(page)
|
|
140
|
+
|
|
141
|
+
console.log('=== GRID RESIZE BENCHMARK ===')
|
|
142
|
+
console.log(`callbacks: ${stats.total}`)
|
|
143
|
+
console.log(`batch time: ${stats.lastTime}ms`)
|
|
144
|
+
console.log(`IO delay warnings: ${warnings.count}`)
|
|
145
|
+
|
|
146
|
+
// gating assertions - 40 grid items should trigger ~40 callbacks
|
|
147
|
+
expect(stats.total, 'grid resize should trigger callbacks').toBeGreaterThan(20)
|
|
148
|
+
expect(warnings.maxDelay, `IO delay should be < ${MAX_IO_DELAY_MS}ms`).toBeLessThan(
|
|
149
|
+
MAX_IO_DELAY_MS
|
|
150
|
+
)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
test('list expand should trigger efficient updates', async ({ page }) => {
|
|
154
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
155
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
156
|
+
await page.waitForTimeout(100)
|
|
157
|
+
|
|
158
|
+
await page.getByTestId('btn-toggle-expand').click()
|
|
159
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
160
|
+
|
|
161
|
+
const stats = await getStats(page)
|
|
162
|
+
const warnings = await collectConsoleWarnings(page)
|
|
163
|
+
|
|
164
|
+
console.log('=== LIST EXPAND BENCHMARK ===')
|
|
165
|
+
console.log(`callbacks: ${stats.total}`)
|
|
166
|
+
console.log(`batch time: ${stats.lastTime}ms`)
|
|
167
|
+
console.log(`IO delay warnings: ${warnings.count}`)
|
|
168
|
+
|
|
169
|
+
// gating assertions - 20 list items should trigger ~20 callbacks
|
|
170
|
+
expect(stats.total, 'list expand should trigger callbacks').toBeGreaterThan(10)
|
|
171
|
+
expect(warnings.maxDelay, `IO delay should be < ${MAX_IO_DELAY_MS}ms`).toBeLessThan(
|
|
172
|
+
MAX_IO_DELAY_MS
|
|
173
|
+
)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test('container resize affects all children', async ({ page }) => {
|
|
177
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
178
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
179
|
+
await page.waitForTimeout(100)
|
|
180
|
+
|
|
181
|
+
await page.getByTestId('btn-resize-container').click()
|
|
182
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
183
|
+
|
|
184
|
+
const stats = await getStats(page)
|
|
185
|
+
const warnings = await collectConsoleWarnings(page)
|
|
186
|
+
|
|
187
|
+
console.log('=== CONTAINER RESIZE BENCHMARK ===')
|
|
188
|
+
console.log(`callbacks: ${stats.total}`)
|
|
189
|
+
console.log(`batch time: ${stats.lastTime}ms`)
|
|
190
|
+
console.log(`IO delay warnings: ${warnings.count}`)
|
|
191
|
+
|
|
192
|
+
// gating assertion
|
|
193
|
+
expect(warnings.maxDelay, `IO delay should be < ${MAX_IO_DELAY_MS}ms`).toBeLessThan(
|
|
194
|
+
MAX_IO_DELAY_MS
|
|
195
|
+
)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
test('rapid successive resizes', async ({ page }) => {
|
|
199
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
200
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
201
|
+
await page.waitForTimeout(100)
|
|
202
|
+
|
|
203
|
+
// rapid fire multiple resize operations
|
|
204
|
+
for (let i = 0; i < 5; i++) {
|
|
205
|
+
await page.getByTestId('btn-resize-width').click()
|
|
206
|
+
await page.waitForTimeout(50)
|
|
207
|
+
await page.getByTestId('btn-resize-grid').click()
|
|
208
|
+
await page.waitForTimeout(50)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
212
|
+
|
|
213
|
+
const stats = await getStats(page)
|
|
214
|
+
const warnings = await collectConsoleWarnings(page)
|
|
215
|
+
|
|
216
|
+
console.log('=== RAPID RESIZE BENCHMARK ===')
|
|
217
|
+
console.log(`total callbacks: ${stats.total}`)
|
|
218
|
+
console.log(`max batch time: ${stats.max}ms`)
|
|
219
|
+
console.log(`IO delay warnings: ${warnings.count}`)
|
|
220
|
+
if (warnings.count > 0) {
|
|
221
|
+
console.log(`avg IO delay: ${warnings.avgDelay}ms`)
|
|
222
|
+
console.log(`max IO delay: ${warnings.maxDelay}ms`)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// gating assertion - rapid resize is stressful but shouldn't explode
|
|
226
|
+
expect(
|
|
227
|
+
warnings.maxDelay,
|
|
228
|
+
`IO delay should be < ${MAX_IO_DELAY_MS}ms even under stress`
|
|
229
|
+
).toBeLessThan(MAX_IO_DELAY_MS)
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
test('full benchmark suite', async ({ page }) => {
|
|
233
|
+
const results: Record<string, any> = {}
|
|
234
|
+
|
|
235
|
+
// initial render
|
|
236
|
+
await page.waitForTimeout(INITIAL_SETTLE_TIME)
|
|
237
|
+
results.initial = {
|
|
238
|
+
...(await getStats(page)),
|
|
239
|
+
warnings: await collectConsoleWarnings(page),
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// width resize
|
|
243
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
244
|
+
await page.waitForTimeout(100)
|
|
245
|
+
await page.getByTestId('btn-resize-width').click()
|
|
246
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
247
|
+
results.widthResize = {
|
|
248
|
+
...(await getStats(page)),
|
|
249
|
+
warnings: await collectConsoleWarnings(page),
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// grid resize
|
|
253
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
254
|
+
await page.waitForTimeout(100)
|
|
255
|
+
await page.getByTestId('btn-resize-grid').click()
|
|
256
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
257
|
+
results.gridResize = {
|
|
258
|
+
...(await getStats(page)),
|
|
259
|
+
warnings: await collectConsoleWarnings(page),
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// expand list
|
|
263
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
264
|
+
await page.waitForTimeout(100)
|
|
265
|
+
await page.getByTestId('btn-toggle-expand').click()
|
|
266
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
267
|
+
results.listExpand = {
|
|
268
|
+
...(await getStats(page)),
|
|
269
|
+
warnings: await collectConsoleWarnings(page),
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// container resize
|
|
273
|
+
await page.getByTestId('btn-reset-stats').click()
|
|
274
|
+
await page.waitForTimeout(100)
|
|
275
|
+
await page.getByTestId('btn-resize-container').click()
|
|
276
|
+
await page.waitForTimeout(POLL_WAIT * 3)
|
|
277
|
+
results.containerResize = {
|
|
278
|
+
...(await getStats(page)),
|
|
279
|
+
warnings: await collectConsoleWarnings(page),
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
console.log('\n========== FULL BENCHMARK RESULTS ==========')
|
|
283
|
+
console.log(JSON.stringify(results, null, 2))
|
|
284
|
+
console.log('=============================================\n')
|
|
285
|
+
|
|
286
|
+
// calculate aggregate metrics
|
|
287
|
+
const allMaxDelays = Object.values(results).map((r: any) => r.warnings?.maxDelay || 0)
|
|
288
|
+
const overallMaxDelay = Math.max(...allMaxDelays)
|
|
289
|
+
const totalWarnings = Object.values(results).reduce(
|
|
290
|
+
(sum: number, r: any) => sum + (r.warnings?.count || 0),
|
|
291
|
+
0
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
console.log(
|
|
295
|
+
`AGGREGATE: ${totalWarnings} total warnings, ${overallMaxDelay}ms max IO delay`
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
// gating assertions for the full suite
|
|
299
|
+
expect(
|
|
300
|
+
overallMaxDelay,
|
|
301
|
+
`max IO delay across all tests should be < ${MAX_IO_DELAY_MS}ms`
|
|
302
|
+
).toBeLessThan(MAX_IO_DELAY_MS)
|
|
303
|
+
})
|
|
304
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
|
|
3
|
+
import { getStyles } from './utils'
|
|
4
|
+
import { setupPage } from './test-utils'
|
|
5
|
+
|
|
6
|
+
test.beforeEach(async ({ page }) => {
|
|
7
|
+
await setupPage(page, { name: 'ParagraphSpanFontInheritance', type: 'useCase' })
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test(`Span inherits $mono fontFamily from Paragraph`, async ({ page }) => {
|
|
11
|
+
const parentStyles = await getStyles(page.getByTestId('parent-mono').first())
|
|
12
|
+
const nestedStyles = await getStyles(page.getByTestId('nested-span-mono').first())
|
|
13
|
+
|
|
14
|
+
// parent should have mono font family
|
|
15
|
+
expect(parentStyles.fontFamily).toContain('mono')
|
|
16
|
+
|
|
17
|
+
// span should inherit the mono font family
|
|
18
|
+
expect(nestedStyles.fontFamily).toBe(parentStyles.fontFamily)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test(`Span inherits $body fontFamily from Paragraph`, async ({ page }) => {
|
|
22
|
+
const parentStyles = await getStyles(page.getByTestId('parent-body').first())
|
|
23
|
+
const nestedStyles = await getStyles(page.getByTestId('nested-span-body').first())
|
|
24
|
+
|
|
25
|
+
// span should inherit the body font family
|
|
26
|
+
expect(nestedStyles.fontFamily).toBe(parentStyles.fontFamily)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test(`nested Text inherits $mono fontFamily from Text (baseline)`, async ({ page }) => {
|
|
30
|
+
const parentStyles = await getStyles(page.getByTestId('parent-text-mono').first())
|
|
31
|
+
const nestedStyles = await getStyles(page.getByTestId('nested-text-mono').first())
|
|
32
|
+
|
|
33
|
+
// parent should have mono font family
|
|
34
|
+
expect(parentStyles.fontFamily).toContain('mono')
|
|
35
|
+
|
|
36
|
+
// nested text should inherit the mono font family
|
|
37
|
+
expect(nestedStyles.fontFamily).toBe(parentStyles.fontFamily)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test(`Span explicit fontFamily override works`, async ({ page }) => {
|
|
41
|
+
const parentStyles = await getStyles(page.getByTestId('parent-mono-override').first())
|
|
42
|
+
const nestedStyles = await getStyles(page.getByTestId('nested-span-override').first())
|
|
43
|
+
|
|
44
|
+
// parent should have mono font family
|
|
45
|
+
expect(parentStyles.fontFamily).toContain('mono')
|
|
46
|
+
|
|
47
|
+
// span with explicit $body should NOT inherit mono
|
|
48
|
+
expect(nestedStyles.fontFamily).not.toBe(parentStyles.fontFamily)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test(`SizableText keeps its explicit fontFamily (does not inherit)`, async ({ page }) => {
|
|
52
|
+
const parentStyles = await getStyles(page.getByTestId('parent-mono-sizable').first())
|
|
53
|
+
const nestedStyles = await getStyles(page.getByTestId('nested-sizable-body').first())
|
|
54
|
+
|
|
55
|
+
// parent should have mono font family
|
|
56
|
+
expect(parentStyles.fontFamily).toContain('mono')
|
|
57
|
+
|
|
58
|
+
// SizableText has explicit fontFamily: '$body' in its static config,
|
|
59
|
+
// so it should NOT inherit mono but keep its body font
|
|
60
|
+
expect(nestedStyles.fontFamily).not.toBe(parentStyles.fontFamily)
|
|
61
|
+
expect(nestedStyles.fontFamily).toContain('Inter')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test(`Text (like Link) inside Paragraph inherits fontFamily`, async ({ page }) => {
|
|
65
|
+
const parentStyles = await getStyles(page.getByTestId('parent-para-link').first())
|
|
66
|
+
const nestedStyles = await getStyles(page.getByTestId('nested-link-text').first())
|
|
67
|
+
|
|
68
|
+
// parent should have mono font family
|
|
69
|
+
expect(parentStyles.fontFamily).toContain('mono')
|
|
70
|
+
|
|
71
|
+
// nested Text should inherit the mono font family
|
|
72
|
+
expect(nestedStyles.fontFamily).toBe(parentStyles.fontFamily)
|
|
73
|
+
})
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
test.beforeEach(async ({ page }) => {
|
|
5
|
+
await setupPage(page, { name: 'PointerEventsCase', type: 'useCase' })
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test('pointer events - down and up fire on click', async ({ page }) => {
|
|
9
|
+
const target = page.locator('[data-testid="pointer-target"]')
|
|
10
|
+
const downCount = page.locator('[data-testid="down-count"]')
|
|
11
|
+
const upCount = page.locator('[data-testid="up-count"]')
|
|
12
|
+
|
|
13
|
+
await expect(downCount).toHaveText('Down: 0')
|
|
14
|
+
await expect(upCount).toHaveText('Up: 0')
|
|
15
|
+
|
|
16
|
+
await target.click()
|
|
17
|
+
|
|
18
|
+
await expect(downCount).toHaveText('Down: 1')
|
|
19
|
+
await expect(upCount).toHaveText('Up: 1')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('pointer events - enter and leave fire on hover', async ({ page }) => {
|
|
23
|
+
const target = page.locator('[data-testid="pointer-target"]')
|
|
24
|
+
const enterCount = page.locator('[data-testid="enter-count"]')
|
|
25
|
+
const leaveCount = page.locator('[data-testid="leave-count"]')
|
|
26
|
+
|
|
27
|
+
await expect(enterCount).toHaveText('Enter: 0')
|
|
28
|
+
await expect(leaveCount).toHaveText('Leave: 0')
|
|
29
|
+
|
|
30
|
+
// hover over target
|
|
31
|
+
await target.hover()
|
|
32
|
+
await expect(enterCount).toHaveText('Enter: 1')
|
|
33
|
+
|
|
34
|
+
// move away from target
|
|
35
|
+
await page.mouse.move(0, 0)
|
|
36
|
+
await expect(leaveCount).toHaveText('Leave: 1')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('pointer events - move fires during drag', async ({ page }) => {
|
|
40
|
+
const target = page.locator('[data-testid="pointer-target"]')
|
|
41
|
+
const moveCount = page.locator('[data-testid="move-count"]')
|
|
42
|
+
|
|
43
|
+
await expect(moveCount).toHaveText('Move: 0')
|
|
44
|
+
|
|
45
|
+
// get the bounding box and move within it
|
|
46
|
+
const box = await target.boundingBox()
|
|
47
|
+
if (!box) throw new Error('Could not get bounding box')
|
|
48
|
+
|
|
49
|
+
// move mouse across the target
|
|
50
|
+
const startX = box.x + 10
|
|
51
|
+
const startY = box.y + 10
|
|
52
|
+
const endX = box.x + box.width - 10
|
|
53
|
+
const endY = box.y + box.height - 10
|
|
54
|
+
|
|
55
|
+
await page.mouse.move(startX, startY)
|
|
56
|
+
await page.mouse.move(endX, endY, { steps: 5 })
|
|
57
|
+
|
|
58
|
+
// should have fired multiple move events
|
|
59
|
+
const text = await moveCount.textContent()
|
|
60
|
+
const count = parseInt(text?.replace('Move: ', '') || '0')
|
|
61
|
+
expect(count).toBeGreaterThan(0)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('pointer events - box-none allows clicks to pass through parent to element behind', async ({
|
|
65
|
+
page,
|
|
66
|
+
}) => {
|
|
67
|
+
const parentCount = page.locator('[data-testid="box-none-parent-count"]')
|
|
68
|
+
const childCount = page.locator('[data-testid="box-none-child-count"]')
|
|
69
|
+
const behindCount = page.locator('[data-testid="box-none-behind-count"]')
|
|
70
|
+
const behind = page.locator('[data-testid="box-none-behind"]')
|
|
71
|
+
|
|
72
|
+
// initial state
|
|
73
|
+
await expect(parentCount).toHaveText('BoxNoneParent: 0')
|
|
74
|
+
await expect(childCount).toHaveText('BoxNoneChild: 0')
|
|
75
|
+
await expect(behindCount).toHaveText('BoxNoneBehind: 0')
|
|
76
|
+
|
|
77
|
+
// click directly on parent area (where behind element is underneath)
|
|
78
|
+
// box-none should let the click pass through to the behind element
|
|
79
|
+
const behindBox = await behind.boundingBox()
|
|
80
|
+
if (!behindBox) throw new Error('Could not get behind bounding box')
|
|
81
|
+
|
|
82
|
+
// get center of the behind element which is covered by the parent
|
|
83
|
+
const centerX = behindBox.x + behindBox.width / 2
|
|
84
|
+
const centerY = behindBox.y + behindBox.height / 2
|
|
85
|
+
|
|
86
|
+
// clicking at this position should:
|
|
87
|
+
// 1. NOT trigger the parent's onPress (box-none means parent ignores pointer events)
|
|
88
|
+
// 2. Trigger the behind element's onPress (click passes through)
|
|
89
|
+
await page.mouse.click(centerX, centerY)
|
|
90
|
+
|
|
91
|
+
// parent should not have received the click
|
|
92
|
+
await expect(parentCount).toHaveText('BoxNoneParent: 0')
|
|
93
|
+
// behind element should have received the click
|
|
94
|
+
await expect(behindCount).toHaveText('BoxNoneBehind: 1')
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
test('pointer events - box-none child still receives clicks', async ({ page }) => {
|
|
98
|
+
const childCount = page.locator('[data-testid="box-none-child-count"]')
|
|
99
|
+
const child = page.locator('[data-testid="box-none-child"]')
|
|
100
|
+
|
|
101
|
+
await expect(childCount).toHaveText('BoxNoneChild: 0')
|
|
102
|
+
|
|
103
|
+
// clicking on child should work (children can still receive events)
|
|
104
|
+
await child.click()
|
|
105
|
+
await expect(childCount).toHaveText('BoxNoneChild: 1')
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
test('pointer events - box-none applies correct CSS', async ({ page }) => {
|
|
109
|
+
const parent = page.locator('[data-testid="box-none-parent"]')
|
|
110
|
+
const child = page.locator('[data-testid="box-none-child"]')
|
|
111
|
+
|
|
112
|
+
// parent should have pointer-events: none
|
|
113
|
+
const parentPointerEvents = await parent.evaluate(
|
|
114
|
+
(el) => window.getComputedStyle(el).pointerEvents
|
|
115
|
+
)
|
|
116
|
+
expect(parentPointerEvents).toBe('none')
|
|
117
|
+
|
|
118
|
+
// direct children should have pointer-events: auto (due to box-none polyfill)
|
|
119
|
+
const childPointerEvents = await child.evaluate(
|
|
120
|
+
(el) => window.getComputedStyle(el).pointerEvents
|
|
121
|
+
)
|
|
122
|
+
expect(childPointerEvents).toBe('auto')
|
|
123
|
+
})
|