@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,104 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Regression tests for transform media query merging bug
|
|
6
|
+
*
|
|
7
|
+
* Bug: When a media query sets transform props like `x`, it should OVERWRITE
|
|
8
|
+
* the base value, not be CUMULATIVE (added together).
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
* - Base: x={-100}
|
|
12
|
+
* - $sm: { x: 50 }
|
|
13
|
+
* - Expected at $sm: x = 50 (overwrite)
|
|
14
|
+
* - Bug behavior: x = -50 (cumulative: -100 + 50)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
test.describe('Transform Media Query Merge', () => {
|
|
18
|
+
test.beforeEach(async ({ page }) => {
|
|
19
|
+
await setupPage(page, { name: 'TransformMediaQueryMerge', type: 'useCase' })
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
// Helper to extract translateX from transform
|
|
23
|
+
async function getTranslateX(page: any, testId: string): Promise<number> {
|
|
24
|
+
return page.evaluate((id: string) => {
|
|
25
|
+
const el = document.querySelector(`[data-testid="${id}"]`)
|
|
26
|
+
if (!el) return NaN
|
|
27
|
+
const transform = getComputedStyle(el).transform
|
|
28
|
+
if (transform === 'none') return 0
|
|
29
|
+
|
|
30
|
+
// Handle matrix(a, b, c, d, tx, ty) format
|
|
31
|
+
const matrixMatch = transform.match(/matrix\(([^)]+)\)/)
|
|
32
|
+
if (matrixMatch) {
|
|
33
|
+
const values = matrixMatch[1].split(',').map((v: string) => parseFloat(v.trim()))
|
|
34
|
+
return values[4] || 0
|
|
35
|
+
}
|
|
36
|
+
return 0
|
|
37
|
+
}, testId)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
test('base transform values apply at large viewport', async ({ page }) => {
|
|
41
|
+
await page.setViewportSize({ width: 1200, height: 800 })
|
|
42
|
+
await page.waitForTimeout(300)
|
|
43
|
+
|
|
44
|
+
// Test 1: styled() component with x=-100 base
|
|
45
|
+
const x1 = await getTranslateX(page, 'test1')
|
|
46
|
+
expect(x1, 'styled component base x=-100').toBeCloseTo(-100, 0)
|
|
47
|
+
|
|
48
|
+
// Test 3: runtime prop with x=-75 base
|
|
49
|
+
const x3 = await getTranslateX(page, 'test3')
|
|
50
|
+
expect(x3, 'runtime prop base x=-75').toBeCloseTo(-75, 0)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('media query x OVERWRITES base value (not cumulative)', async ({ page }) => {
|
|
54
|
+
// Set viewport to $sm breakpoint
|
|
55
|
+
await page.setViewportSize({ width: 600, height: 800 })
|
|
56
|
+
await page.waitForTimeout(300)
|
|
57
|
+
|
|
58
|
+
// Test 1: styled() with base x=-100, $sm: x=50
|
|
59
|
+
// If cumulative (bug): x = -100 + 50 = -50
|
|
60
|
+
// If overwrite (correct): x = 50
|
|
61
|
+
const x1 = await getTranslateX(page, 'test1')
|
|
62
|
+
expect(x1, 'styled $sm x should OVERWRITE to 50, not cumulate to -50').toBeCloseTo(
|
|
63
|
+
50,
|
|
64
|
+
0
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('runtime prop media query x OVERWRITES base value', async ({ page }) => {
|
|
69
|
+
await page.setViewportSize({ width: 600, height: 800 })
|
|
70
|
+
await page.waitForTimeout(300)
|
|
71
|
+
|
|
72
|
+
// Test 3: runtime prop with base x=-75, $sm: x=75
|
|
73
|
+
// If cumulative (bug): x = -75 + 75 = 0
|
|
74
|
+
// If overwrite (correct): x = 75
|
|
75
|
+
const x3 = await getTranslateX(page, 'test3')
|
|
76
|
+
expect(x3, 'runtime $sm x should OVERWRITE to 75, not cumulate to 0').toBeCloseTo(
|
|
77
|
+
75,
|
|
78
|
+
0
|
|
79
|
+
)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('viewport resize updates transform correctly', async ({ page }) => {
|
|
83
|
+
// Start large - should have base value
|
|
84
|
+
await page.setViewportSize({ width: 1200, height: 800 })
|
|
85
|
+
await page.waitForTimeout(300)
|
|
86
|
+
|
|
87
|
+
let x1 = await getTranslateX(page, 'test1')
|
|
88
|
+
expect(x1, 'large viewport: x=-100').toBeCloseTo(-100, 0)
|
|
89
|
+
|
|
90
|
+
// Resize to small - should overwrite to media query value
|
|
91
|
+
await page.setViewportSize({ width: 600, height: 800 })
|
|
92
|
+
await page.waitForTimeout(300)
|
|
93
|
+
|
|
94
|
+
x1 = await getTranslateX(page, 'test1')
|
|
95
|
+
expect(x1, 'small viewport: x should be 50 (overwrite)').toBeCloseTo(50, 0)
|
|
96
|
+
|
|
97
|
+
// Resize back to large - should return to base value
|
|
98
|
+
await page.setViewportSize({ width: 1200, height: 800 })
|
|
99
|
+
await page.waitForTimeout(300)
|
|
100
|
+
|
|
101
|
+
x1 = await getTranslateX(page, 'test1')
|
|
102
|
+
expect(x1, 'back to large: x=-100').toBeCloseTo(-100, 0)
|
|
103
|
+
})
|
|
104
|
+
})
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { expect, test, type Page } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ENTER/EXIT TRANSITION TESTS
|
|
6
|
+
*
|
|
7
|
+
* Tests the transition prop's enter/exit-specific animations using timing animations.
|
|
8
|
+
* Supports syntax like: transition={{ enter: '500ms', exit: '100ms' }}
|
|
9
|
+
*
|
|
10
|
+
* These tests run across all animation drivers (css, native, reanimated, motion).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const TOLERANCE = 0.2
|
|
14
|
+
|
|
15
|
+
async function getOpacity(page: Page, testId: string): Promise<number> {
|
|
16
|
+
return page.evaluate((id) => {
|
|
17
|
+
const el = document.querySelector(`[data-testid="${id}"]`)
|
|
18
|
+
if (!el) return -1
|
|
19
|
+
return Number.parseFloat(getComputedStyle(el).opacity)
|
|
20
|
+
}, testId)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function elementExists(page: Page, testId: string): Promise<boolean> {
|
|
24
|
+
return page.evaluate((id) => !!document.querySelector(`[data-testid="${id}"]`), testId)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isIntermediate(
|
|
28
|
+
value: number,
|
|
29
|
+
start: number,
|
|
30
|
+
end: number,
|
|
31
|
+
tolerance = TOLERANCE
|
|
32
|
+
): boolean {
|
|
33
|
+
const notAtStart = Math.abs(value - start) > tolerance
|
|
34
|
+
const notAtEnd = Math.abs(value - end) > tolerance
|
|
35
|
+
const min = Math.min(start, end)
|
|
36
|
+
const max = Math.max(start, end)
|
|
37
|
+
const inRange = value >= min - tolerance && value <= max + tolerance
|
|
38
|
+
return notAtStart && notAtEnd && inRange
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// works in ci, flaky on local
|
|
42
|
+
test.fixme('Enter/Exit Transition Props', () => {
|
|
43
|
+
test.beforeEach(async ({ page }) => {
|
|
44
|
+
const driver = (test.info().project?.metadata as any)?.animationDriver
|
|
45
|
+
test.skip(driver === 'native', 'native driver has element detection issues on web')
|
|
46
|
+
|
|
47
|
+
await setupPage(page, {
|
|
48
|
+
name: 'AnimationComprehensiveCase',
|
|
49
|
+
type: 'useCase',
|
|
50
|
+
})
|
|
51
|
+
// wait for initial render and any enter animations to complete
|
|
52
|
+
// use longer timeout for CI environments which can be slower
|
|
53
|
+
await page.waitForTimeout(1500)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('scenario 42: different enter/exit transitions - enter uses slow animation', async ({
|
|
57
|
+
page,
|
|
58
|
+
}) => {
|
|
59
|
+
expect(await elementExists(page, 'scenario-42-target'), 'Initially visible').toBe(
|
|
60
|
+
true
|
|
61
|
+
)
|
|
62
|
+
// wait for initial enter animation to complete (500ms animation + settling time)
|
|
63
|
+
await page.waitForFunction(
|
|
64
|
+
(testId) => {
|
|
65
|
+
const el = document.querySelector(`[data-testid="${testId}"]`)
|
|
66
|
+
return el && Number.parseFloat(getComputedStyle(el).opacity) >= 0.95
|
|
67
|
+
},
|
|
68
|
+
'scenario-42-target',
|
|
69
|
+
{ timeout: 3000 }
|
|
70
|
+
)
|
|
71
|
+
expect(await getOpacity(page, 'scenario-42-target'), 'Initial opacity').toBeCloseTo(
|
|
72
|
+
1,
|
|
73
|
+
1
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
// hide then show to test enter animation (enter=500ms)
|
|
77
|
+
await page.getByTestId('scenario-42-trigger').click()
|
|
78
|
+
await page.waitForTimeout(300) // exit=100ms + buffer
|
|
79
|
+
|
|
80
|
+
expect(await elementExists(page, 'scenario-42-target'), 'Hidden').toBe(false)
|
|
81
|
+
|
|
82
|
+
await page.getByTestId('scenario-42-trigger').click()
|
|
83
|
+
await page.waitForTimeout(50)
|
|
84
|
+
expect(await elementExists(page, 'scenario-42-target'), 'Should appear').toBe(true)
|
|
85
|
+
|
|
86
|
+
await page.waitForTimeout(150)
|
|
87
|
+
const midEnterOpacity = await getOpacity(page, 'scenario-42-target')
|
|
88
|
+
|
|
89
|
+
expect(
|
|
90
|
+
isIntermediate(midEnterOpacity, 0, 1),
|
|
91
|
+
`Mid-enter opacity (${midEnterOpacity.toFixed(2)}) should be intermediate at 200ms into 500ms`
|
|
92
|
+
).toBe(true)
|
|
93
|
+
|
|
94
|
+
await page.waitForTimeout(500)
|
|
95
|
+
expect(await getOpacity(page, 'scenario-42-target'), 'Final opacity').toBeCloseTo(
|
|
96
|
+
1,
|
|
97
|
+
1
|
|
98
|
+
)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
test('scenario 42: different enter/exit transitions - exit uses fast animation', async ({
|
|
102
|
+
page,
|
|
103
|
+
}) => {
|
|
104
|
+
expect(await elementExists(page, 'scenario-42-target'), 'Initially visible').toBe(
|
|
105
|
+
true
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
// trigger exit (exit=100ms - fast)
|
|
109
|
+
await page.getByTestId('scenario-42-trigger').click()
|
|
110
|
+
await page.waitForTimeout(300) // 100ms + buffer
|
|
111
|
+
|
|
112
|
+
expect(await elementExists(page, 'scenario-42-target'), 'Gone after fast exit').toBe(
|
|
113
|
+
false
|
|
114
|
+
)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test('scenario 43: enter-only transition - enter uses specified, exit uses default', async ({
|
|
118
|
+
page,
|
|
119
|
+
}) => {
|
|
120
|
+
// enter=500ms, exit uses default=100ms
|
|
121
|
+
expect(await elementExists(page, 'scenario-43-target'), 'Initially visible').toBe(
|
|
122
|
+
true
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
// hide - uses default=100ms (fast)
|
|
126
|
+
await page.getByTestId('scenario-43-trigger').click()
|
|
127
|
+
await page.waitForTimeout(300)
|
|
128
|
+
expect(await elementExists(page, 'scenario-43-target'), 'Hidden').toBe(false)
|
|
129
|
+
|
|
130
|
+
// show - uses enter=500ms (slow)
|
|
131
|
+
await page.getByTestId('scenario-43-trigger').click()
|
|
132
|
+
await page.waitForTimeout(200)
|
|
133
|
+
const midOpacity = await getOpacity(page, 'scenario-43-target')
|
|
134
|
+
|
|
135
|
+
expect(
|
|
136
|
+
isIntermediate(midOpacity, 0, 1),
|
|
137
|
+
`Enter opacity (${midOpacity.toFixed(2)}) should be intermediate at 200ms into 500ms`
|
|
138
|
+
).toBe(true)
|
|
139
|
+
|
|
140
|
+
await page.waitForTimeout(500)
|
|
141
|
+
expect(await getOpacity(page, 'scenario-43-target'), 'Final').toBeCloseTo(1, 1)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
test('scenario 44: exit-only transition - exit uses specified 500ms (slow)', async ({
|
|
145
|
+
page,
|
|
146
|
+
}) => {
|
|
147
|
+
// exit=500ms, enter uses default=100ms
|
|
148
|
+
expect(await elementExists(page, 'scenario-44-target'), 'Initially visible').toBe(
|
|
149
|
+
true
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
// trigger exit - uses 500ms (slow)
|
|
153
|
+
await page.getByTestId('scenario-44-trigger').click()
|
|
154
|
+
|
|
155
|
+
// at 200ms into a 500ms animation, should still be in progress
|
|
156
|
+
await page.waitForTimeout(200)
|
|
157
|
+
|
|
158
|
+
expect(
|
|
159
|
+
await elementExists(page, 'scenario-44-target'),
|
|
160
|
+
'Still exists during 500ms exit'
|
|
161
|
+
).toBe(true)
|
|
162
|
+
const midOpacity = await getOpacity(page, 'scenario-44-target')
|
|
163
|
+
|
|
164
|
+
// with 500ms exit, opacity should still be intermediate at 200ms
|
|
165
|
+
expect(
|
|
166
|
+
isIntermediate(midOpacity, 1, 0),
|
|
167
|
+
`Mid-exit opacity (${midOpacity.toFixed(2)}) should be intermediate at 200ms into 500ms`
|
|
168
|
+
).toBe(true)
|
|
169
|
+
|
|
170
|
+
// wait for completion (500ms + buffer)
|
|
171
|
+
await page.waitForTimeout(500)
|
|
172
|
+
expect(await elementExists(page, 'scenario-44-target'), 'Gone after 500ms exit').toBe(
|
|
173
|
+
false
|
|
174
|
+
)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
test('scenario 45: enter/exit/default - property changes use default animation', async ({
|
|
178
|
+
page,
|
|
179
|
+
}) => {
|
|
180
|
+
// enter=300ms, exit=100ms, default=500ms for property changes
|
|
181
|
+
expect(await elementExists(page, 'scenario-45-target'), 'Initially visible').toBe(
|
|
182
|
+
true
|
|
183
|
+
)
|
|
184
|
+
const initialOpacity = await getOpacity(page, 'scenario-45-target')
|
|
185
|
+
expect(initialOpacity, 'Initial opacity').toBeCloseTo(1, 1)
|
|
186
|
+
|
|
187
|
+
// click prop button to change opacity (not enter/exit, so uses default=500ms)
|
|
188
|
+
await page.getByTestId('scenario-45-trigger-prop').click()
|
|
189
|
+
|
|
190
|
+
// at 150ms into 500ms animation, should be animating (not yet at final 0.5)
|
|
191
|
+
await page.waitForTimeout(150)
|
|
192
|
+
const midOpacity = await getOpacity(page, 'scenario-45-target')
|
|
193
|
+
|
|
194
|
+
// should still be above final value since animation takes 500ms
|
|
195
|
+
expect(
|
|
196
|
+
midOpacity,
|
|
197
|
+
`Mid opacity (${midOpacity.toFixed(2)}) should still be above 0.6`
|
|
198
|
+
).toBeGreaterThan(0.6)
|
|
199
|
+
|
|
200
|
+
// wait for completion (500ms animation + buffer)
|
|
201
|
+
await page.waitForTimeout(500)
|
|
202
|
+
expect(await getOpacity(page, 'scenario-45-target'), 'Final opacity').toBeCloseTo(
|
|
203
|
+
0.5,
|
|
204
|
+
1
|
|
205
|
+
)
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
test('scenario 46: enter/exit with per-property config - opacity uses its own animation', async ({
|
|
209
|
+
page,
|
|
210
|
+
}) => {
|
|
211
|
+
// enter=300ms for scale, exit=100ms for scale, but opacity always=500ms
|
|
212
|
+
// hide first
|
|
213
|
+
await page.getByTestId('scenario-46-trigger').click()
|
|
214
|
+
await page.waitForTimeout(700) // opacity=500ms + buffer
|
|
215
|
+
|
|
216
|
+
expect(await elementExists(page, 'scenario-46-target'), 'Hidden').toBe(false)
|
|
217
|
+
|
|
218
|
+
// show - opacity should use 500ms even though enter=300ms for other props
|
|
219
|
+
await page.getByTestId('scenario-46-trigger').click()
|
|
220
|
+
await page.waitForTimeout(200)
|
|
221
|
+
|
|
222
|
+
const midOpacity = await getOpacity(page, 'scenario-46-target')
|
|
223
|
+
|
|
224
|
+
// at 200ms into 500ms opacity animation, should be intermediate
|
|
225
|
+
expect(
|
|
226
|
+
isIntermediate(midOpacity, 0, 1),
|
|
227
|
+
`Mid-enter opacity (${midOpacity.toFixed(2)}) should be intermediate at 200ms into 500ms`
|
|
228
|
+
).toBe(true)
|
|
229
|
+
|
|
230
|
+
await page.waitForTimeout(500)
|
|
231
|
+
expect(await getOpacity(page, 'scenario-46-target'), 'Final').toBeCloseTo(1, 1)
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
test('scenario 47: enter/exit with delay - animations start after delay', async ({
|
|
235
|
+
page,
|
|
236
|
+
}) => {
|
|
237
|
+
// enter=300ms, exit=100ms, delay=200ms
|
|
238
|
+
// hide first to test enter animation with delay
|
|
239
|
+
await page.getByTestId('scenario-47-trigger').click()
|
|
240
|
+
await page.waitForTimeout(600) // 200ms delay + 100ms exit + buffer
|
|
241
|
+
|
|
242
|
+
expect(await elementExists(page, 'scenario-47-target'), 'Hidden').toBe(false)
|
|
243
|
+
|
|
244
|
+
// show - should have 200ms delay before enter animation starts
|
|
245
|
+
await page.getByTestId('scenario-47-trigger').click()
|
|
246
|
+
|
|
247
|
+
// element appears but at 100ms (during delay), should still be at enterStyle values
|
|
248
|
+
await page.waitForTimeout(100)
|
|
249
|
+
expect(
|
|
250
|
+
await elementExists(page, 'scenario-47-target'),
|
|
251
|
+
'Should appear immediately'
|
|
252
|
+
).toBe(true)
|
|
253
|
+
|
|
254
|
+
const duringDelayOpacity = await getOpacity(page, 'scenario-47-target')
|
|
255
|
+
// during 200ms delay, opacity should be near 0 (enterStyle)
|
|
256
|
+
expect(duringDelayOpacity, 'During delay, should be at enterStyle').toBeLessThan(0.3)
|
|
257
|
+
|
|
258
|
+
// after delay + some animation time (200ms delay + ~150ms into 300ms animation)
|
|
259
|
+
await page.waitForTimeout(250)
|
|
260
|
+
const afterDelayOpacity = await getOpacity(page, 'scenario-47-target')
|
|
261
|
+
// should be animating or completed by now
|
|
262
|
+
expect(afterDelayOpacity, 'After delay, should be animating').toBeGreaterThan(0.3)
|
|
263
|
+
|
|
264
|
+
// wait for full completion
|
|
265
|
+
await page.waitForTimeout(500)
|
|
266
|
+
expect(await getOpacity(page, 'scenario-47-target'), 'Final').toBeCloseTo(1, 1)
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
test('enter animation timing differs from exit timing', async ({ page }) => {
|
|
270
|
+
// scenario 42 uses enter=500ms, exit=100ms
|
|
271
|
+
const startTime = Date.now()
|
|
272
|
+
|
|
273
|
+
// trigger exit
|
|
274
|
+
await page.getByTestId('scenario-42-trigger').click()
|
|
275
|
+
|
|
276
|
+
// wait for element to disappear
|
|
277
|
+
await page.waitForFunction(
|
|
278
|
+
(testId) => !document.querySelector(`[data-testid="${testId}"]`),
|
|
279
|
+
'scenario-42-target',
|
|
280
|
+
{ timeout: 5000 }
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
const exitDuration = Date.now() - startTime
|
|
284
|
+
|
|
285
|
+
// exit should be fast (100ms + overhead)
|
|
286
|
+
expect(exitDuration, 'Exit should be fast').toBeLessThan(500)
|
|
287
|
+
|
|
288
|
+
// now trigger enter
|
|
289
|
+
const enterStart = Date.now()
|
|
290
|
+
await page.getByTestId('scenario-42-trigger').click()
|
|
291
|
+
|
|
292
|
+
// wait for element to fully appear
|
|
293
|
+
await page.waitForTimeout(100)
|
|
294
|
+
await page.waitForFunction(
|
|
295
|
+
(testId) => {
|
|
296
|
+
const el = document.querySelector(`[data-testid="${testId}"]`)
|
|
297
|
+
if (!el) return false
|
|
298
|
+
return Number.parseFloat(getComputedStyle(el).opacity) > 0.9
|
|
299
|
+
},
|
|
300
|
+
'scenario-42-target',
|
|
301
|
+
{ timeout: 5000 }
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
const enterDuration = Date.now() - enterStart
|
|
305
|
+
|
|
306
|
+
// enter should be slower than exit
|
|
307
|
+
expect(enterDuration, 'Enter should be slower than exit').toBeGreaterThan(
|
|
308
|
+
exitDuration
|
|
309
|
+
)
|
|
310
|
+
})
|
|
311
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
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: 'UseTheme', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test(`useTheme() returns right values`, async ({ page }) => {
|
|
10
|
+
expect(await page.locator('#theme-get').innerText()).toBe(`var(--background)`)
|
|
11
|
+
// themeDev uses hsla format
|
|
12
|
+
expect(await page.locator('#theme-val').innerText()).toBe(`hsla(0, 0%, 100%, 1)`)
|
|
13
|
+
expect(await page.locator('#token-get').innerText()).toBe(`var(--blue1)`)
|
|
14
|
+
// Updated for Radix v3 hex format
|
|
15
|
+
expect(await page.locator('#token-val').innerText()).toBe(`#fbfdff`)
|
|
16
|
+
})
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { TEST_IDS } from '../src/constants/test-ids'
|
|
3
|
+
|
|
4
|
+
import { setupPage } from './test-utils'
|
|
5
|
+
import { getStyles } from './utils'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Tests for the v5 theme builder output, covering the documented accent usage patterns:
|
|
9
|
+
*
|
|
10
|
+
* 1. <Theme name="accent"> - theme-builder.mdx, how-to-upgrade.mdx
|
|
11
|
+
* 2. <Button theme="accent"> - config-v5.mdx, ButtonDemo.tsx
|
|
12
|
+
* 3. $accentBackground / $accentColor - config-v5.mdx
|
|
13
|
+
* 4. $accent1-$accent12 raw tokens
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
test.beforeEach(async ({ page }) => {
|
|
17
|
+
await setupPage(page, {
|
|
18
|
+
name: 'V5ThemeBuilderOutput',
|
|
19
|
+
type: 'useCase',
|
|
20
|
+
searchParams: { generatedV5: 'true' },
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// --- <Theme name="accent"> ---
|
|
25
|
+
|
|
26
|
+
test('<Theme name="accent"> $background differs from base $background', async ({
|
|
27
|
+
page,
|
|
28
|
+
}) => {
|
|
29
|
+
const baseEl = page.getByTestId(TEST_IDS.baseBackground)
|
|
30
|
+
const accentEl = page.getByTestId(TEST_IDS.accentThemeBackground)
|
|
31
|
+
|
|
32
|
+
await expect(baseEl).toBeVisible()
|
|
33
|
+
await expect(accentEl).toBeVisible()
|
|
34
|
+
|
|
35
|
+
const baseStyles = await getStyles(baseEl)
|
|
36
|
+
const accentStyles = await getStyles(accentEl)
|
|
37
|
+
|
|
38
|
+
// The accent theme should produce a visually different background from the base theme
|
|
39
|
+
expect(accentStyles.backgroundColor).not.toBe(baseStyles.backgroundColor)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test('<Theme name="accent"> $background is not gray (has color)', async ({ page }) => {
|
|
43
|
+
const accentEl = page.getByTestId(TEST_IDS.accentThemeBackground)
|
|
44
|
+
await expect(accentEl).toBeVisible()
|
|
45
|
+
|
|
46
|
+
const styles = await getStyles(accentEl)
|
|
47
|
+
|
|
48
|
+
// The generated theme has a purple accent (hue 250). Verify it's not a pure gray.
|
|
49
|
+
// In a gray color, r === g === b. A colored accent will have channel differences.
|
|
50
|
+
const match = styles.backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/)
|
|
51
|
+
expect(match).toBeTruthy()
|
|
52
|
+
|
|
53
|
+
if (match) {
|
|
54
|
+
const [, r, g, b] = match.map(Number)
|
|
55
|
+
const isGray = r === g && g === b
|
|
56
|
+
expect(isGray).toBe(false)
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('<Theme name="accent"> $color is defined', async ({ page }) => {
|
|
61
|
+
const textEl = page.getByTestId(TEST_IDS.accentThemeColor)
|
|
62
|
+
await expect(textEl).toBeVisible()
|
|
63
|
+
|
|
64
|
+
const styles = await getStyles(textEl)
|
|
65
|
+
expect(styles.color).toBeDefined()
|
|
66
|
+
expect(styles.color).not.toBe('')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
// --- <Button theme="accent"> ---
|
|
70
|
+
|
|
71
|
+
test('<Button theme="accent"> has different background than base button', async ({
|
|
72
|
+
page,
|
|
73
|
+
}) => {
|
|
74
|
+
const baseBtn = page.getByTestId(TEST_IDS.baseButton)
|
|
75
|
+
const accentBtn = page.getByTestId(TEST_IDS.accentPropButton)
|
|
76
|
+
|
|
77
|
+
await expect(baseBtn).toBeVisible()
|
|
78
|
+
await expect(accentBtn).toBeVisible()
|
|
79
|
+
|
|
80
|
+
const baseStyles = await getStyles(baseBtn)
|
|
81
|
+
const accentStyles = await getStyles(accentBtn)
|
|
82
|
+
|
|
83
|
+
// Accent button should look different from the default button
|
|
84
|
+
expect(accentStyles.backgroundColor).not.toBe(baseStyles.backgroundColor)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('<Button theme="accent"> background is not gray', async ({ page }) => {
|
|
88
|
+
const accentBtn = page.getByTestId(TEST_IDS.accentPropButton)
|
|
89
|
+
await expect(accentBtn).toBeVisible()
|
|
90
|
+
|
|
91
|
+
const styles = await getStyles(accentBtn)
|
|
92
|
+
|
|
93
|
+
const match = styles.backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/)
|
|
94
|
+
expect(match).toBeTruthy()
|
|
95
|
+
|
|
96
|
+
if (match) {
|
|
97
|
+
const [, r, g, b] = match.map(Number)
|
|
98
|
+
const isGray = r === g && g === b
|
|
99
|
+
expect(isGray).toBe(false)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// --- $accentBackground token ---
|
|
104
|
+
|
|
105
|
+
test('$accentBackground token resolves to a non-gray color', async ({ page }) => {
|
|
106
|
+
const el = page.getByTestId(TEST_IDS.accentBgToken)
|
|
107
|
+
await expect(el).toBeVisible()
|
|
108
|
+
|
|
109
|
+
const styles = await getStyles(el)
|
|
110
|
+
expect(styles.backgroundColor).toBeDefined()
|
|
111
|
+
expect(styles.backgroundColor).not.toBe('')
|
|
112
|
+
|
|
113
|
+
const match = styles.backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/)
|
|
114
|
+
expect(match).toBeTruthy()
|
|
115
|
+
|
|
116
|
+
if (match) {
|
|
117
|
+
const [, r, g, b] = match.map(Number)
|
|
118
|
+
const isGray = r === g && g === b
|
|
119
|
+
expect(isGray).toBe(false)
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// --- $accent1-12 raw tokens ---
|
|
124
|
+
|
|
125
|
+
test('$accent1-12 palette tokens render a gradient (not all identical)', async ({
|
|
126
|
+
page,
|
|
127
|
+
}) => {
|
|
128
|
+
const colors: string[] = []
|
|
129
|
+
|
|
130
|
+
for (let i = 1; i <= 12; i++) {
|
|
131
|
+
const swatch = page.getByTestId(`palette-accent-${i}`)
|
|
132
|
+
await expect(swatch).toBeVisible()
|
|
133
|
+
|
|
134
|
+
const styles = await getStyles(swatch)
|
|
135
|
+
expect(styles.backgroundColor).toBeDefined()
|
|
136
|
+
colors.push(styles.backgroundColor)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Palette should have multiple distinct values (a gradient, not flat)
|
|
140
|
+
const uniqueColors = new Set(colors)
|
|
141
|
+
expect(uniqueColors.size).toBeGreaterThan(1)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// --- Color child themes ---
|
|
145
|
+
|
|
146
|
+
test('color child themes (yellow, red, green, blue) have distinct backgrounds', async ({
|
|
147
|
+
page,
|
|
148
|
+
}) => {
|
|
149
|
+
const yellowBtn = page.getByTestId('button-yellow')
|
|
150
|
+
const redBtn = page.getByTestId('button-red')
|
|
151
|
+
const greenBtn = page.getByTestId('button-green')
|
|
152
|
+
|
|
153
|
+
await expect(yellowBtn).toBeVisible()
|
|
154
|
+
await expect(redBtn).toBeVisible()
|
|
155
|
+
await expect(greenBtn).toBeVisible()
|
|
156
|
+
|
|
157
|
+
const yellowStyles = await getStyles(yellowBtn)
|
|
158
|
+
const redStyles = await getStyles(redBtn)
|
|
159
|
+
const greenStyles = await getStyles(greenBtn)
|
|
160
|
+
|
|
161
|
+
expect(yellowStyles.backgroundColor).not.toBe(redStyles.backgroundColor)
|
|
162
|
+
expect(redStyles.backgroundColor).not.toBe(greenStyles.backgroundColor)
|
|
163
|
+
expect(yellowStyles.backgroundColor).not.toBe(greenStyles.backgroundColor)
|
|
164
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
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: 'VariantFontFamily', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test(`testing things...`, async ({ page }) => {
|
|
10
|
+
await expect(page.getByTestId('heading').first()).toHaveCSS('font-size', '11px')
|
|
11
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
|
|
3
|
+
import { setupPage } from './test-utils'
|
|
4
|
+
import { getStyles } from './utils'
|
|
5
|
+
|
|
6
|
+
test.beforeEach(async ({ page }) => {
|
|
7
|
+
await setupPage(page, { name: 'VariantsOrder', type: 'useCase' })
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test(`variants apply below default props but above parent defaultvariants/props as you nest styled()`, async ({
|
|
11
|
+
page,
|
|
12
|
+
}) => {
|
|
13
|
+
expect(await getStyles(page.getByTestId('button').first())).toMatchObject({
|
|
14
|
+
flexDirection: 'row',
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
expect(await getStyles(page.getByTestId('text1').first())).toMatchObject({
|
|
18
|
+
fontSize: '16px',
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
expect(await getStyles(page.getByTestId('text2').first())).toMatchObject({
|
|
22
|
+
fontSize: '15px',
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
expect(await getStyles(page.getByTestId('text3').first())).toMatchObject({
|
|
26
|
+
fontSize: '30px',
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
expect(await getStyles(page.getByTestId('text4').first())).toMatchObject({
|
|
30
|
+
fontSize: '40px',
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
// Issue #3669: https://github.com/hanzoai/gui/issues/3669
|
|
35
|
+
test(`variant chaining: child variant (test2) translates to parent variant (test) and propagates via context`, async ({
|
|
36
|
+
page,
|
|
37
|
+
}) => {
|
|
38
|
+
// Direct test=true on ButtonFrame
|
|
39
|
+
const directFrame = await getStyles(page.getByTestId('frame-test-direct').first())
|
|
40
|
+
expect(directFrame.backgroundColor).toBe('rgb(255, 0, 0)') // red
|
|
41
|
+
|
|
42
|
+
// test2=true on ButtonFrame2 should translate to test=true
|
|
43
|
+
const chainedFrame = await getStyles(page.getByTestId('frame-test2-chained').first())
|
|
44
|
+
expect(chainedFrame.backgroundColor).toBe('rgb(255, 0, 0)') // same red
|
|
45
|
+
|
|
46
|
+
// ButtonText inside direct test should get white color via context
|
|
47
|
+
const directText = await getStyles(page.getByTestId('text-test-direct').first())
|
|
48
|
+
expect(directText.color).toBe('rgb(255, 255, 255)') // white
|
|
49
|
+
|
|
50
|
+
// ButtonText inside chained test2 should also get white via context
|
|
51
|
+
const chainedText = await getStyles(page.getByTestId('text-test2-chained').first())
|
|
52
|
+
expect(chainedText.color).toBe('rgb(255, 255, 255)') // white - this is the regression
|
|
53
|
+
})
|