@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,259 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
test.beforeEach(async ({ page }) => {
|
|
5
|
+
await setupPage(page, { name: 'SheetSnapPointsFitCase', type: 'useCase' })
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test.describe('Sheet snapPointsMode="fit"', () => {
|
|
9
|
+
test('standalone sheet with fit mode opens and closes without issues', async ({
|
|
10
|
+
page,
|
|
11
|
+
}) => {
|
|
12
|
+
const trigger = page.getByTestId('standalone-fit-trigger')
|
|
13
|
+
const frame = page.getByTestId('standalone-fit-frame')
|
|
14
|
+
const closeButton = page.getByTestId('standalone-fit-close')
|
|
15
|
+
|
|
16
|
+
// Initial state - sheet should not be visible
|
|
17
|
+
await expect(trigger).toBeVisible()
|
|
18
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
19
|
+
|
|
20
|
+
// Open the sheet
|
|
21
|
+
await trigger.click()
|
|
22
|
+
|
|
23
|
+
// Wait for sheet to be visible
|
|
24
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
25
|
+
|
|
26
|
+
// Close the sheet
|
|
27
|
+
await closeButton.click()
|
|
28
|
+
|
|
29
|
+
// Wait for animation to complete
|
|
30
|
+
await page.waitForTimeout(500)
|
|
31
|
+
|
|
32
|
+
// Sheet should not be visible
|
|
33
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('standalone sheet with percent mode opens and closes without issues', async ({
|
|
37
|
+
page,
|
|
38
|
+
}) => {
|
|
39
|
+
const trigger = page.getByTestId('standalone-percent-trigger')
|
|
40
|
+
const frame = page.getByTestId('standalone-percent-frame')
|
|
41
|
+
const closeButton = page.getByTestId('standalone-percent-close')
|
|
42
|
+
|
|
43
|
+
await expect(trigger).toBeVisible()
|
|
44
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
45
|
+
|
|
46
|
+
await trigger.click()
|
|
47
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
48
|
+
|
|
49
|
+
await closeButton.click()
|
|
50
|
+
await page.waitForTimeout(500)
|
|
51
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('standalone sheet with constant mode opens and closes without issues', async ({
|
|
55
|
+
page,
|
|
56
|
+
}) => {
|
|
57
|
+
const trigger = page.getByTestId('standalone-constant-trigger')
|
|
58
|
+
const frame = page.getByTestId('standalone-constant-frame')
|
|
59
|
+
const closeButton = page.getByTestId('standalone-constant-close')
|
|
60
|
+
|
|
61
|
+
await expect(trigger).toBeVisible()
|
|
62
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
63
|
+
|
|
64
|
+
await trigger.click()
|
|
65
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
66
|
+
|
|
67
|
+
await closeButton.click()
|
|
68
|
+
await page.waitForTimeout(500)
|
|
69
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('rapid open/close interactions work correctly', async ({ page }) => {
|
|
73
|
+
const trigger = page.getByTestId('rapid-toggle-trigger')
|
|
74
|
+
const frame = page.getByTestId('rapid-frame')
|
|
75
|
+
const closeButton = page.getByTestId('rapid-close')
|
|
76
|
+
|
|
77
|
+
await expect(trigger).toBeVisible()
|
|
78
|
+
|
|
79
|
+
// Open the sheet
|
|
80
|
+
await trigger.click()
|
|
81
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
82
|
+
|
|
83
|
+
// Close and reopen rapidly a few times using the close button
|
|
84
|
+
for (let i = 0; i < 3; i++) {
|
|
85
|
+
await closeButton.click()
|
|
86
|
+
await page.waitForTimeout(300) // Wait for close animation
|
|
87
|
+
await trigger.click()
|
|
88
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Final close
|
|
92
|
+
await closeButton.click()
|
|
93
|
+
await page.waitForTimeout(500)
|
|
94
|
+
|
|
95
|
+
// Sheet should be closed now
|
|
96
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('dynamic content changes while sheet is open', async ({ page }) => {
|
|
100
|
+
const trigger = page.getByTestId('dynamic-content-trigger')
|
|
101
|
+
const frame = page.getByTestId('dynamic-content-frame')
|
|
102
|
+
const closeButton = page.getByTestId('dynamic-content-close')
|
|
103
|
+
const sizeText = page.getByTestId('dynamic-content-size')
|
|
104
|
+
const smallButton = page.getByTestId('dynamic-content-small')
|
|
105
|
+
const mediumButton = page.getByTestId('dynamic-content-medium')
|
|
106
|
+
const largeButton = page.getByTestId('dynamic-content-large')
|
|
107
|
+
|
|
108
|
+
// Open the sheet
|
|
109
|
+
await trigger.click()
|
|
110
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
111
|
+
|
|
112
|
+
// Initial size should be small
|
|
113
|
+
await expect(sizeText).toContainText('small')
|
|
114
|
+
|
|
115
|
+
// Get initial frame height
|
|
116
|
+
const initialBox = await frame.boundingBox()
|
|
117
|
+
const initialHeight = initialBox?.height ?? 0
|
|
118
|
+
|
|
119
|
+
// Change to medium content
|
|
120
|
+
await mediumButton.click()
|
|
121
|
+
await expect(sizeText).toContainText('medium')
|
|
122
|
+
await page.waitForTimeout(300) // Wait for resize animation
|
|
123
|
+
|
|
124
|
+
// Get medium frame height - should be larger
|
|
125
|
+
const mediumBox = await frame.boundingBox()
|
|
126
|
+
const mediumHeight = mediumBox?.height ?? 0
|
|
127
|
+
expect(mediumHeight).toBeGreaterThan(initialHeight)
|
|
128
|
+
|
|
129
|
+
// Change to large content
|
|
130
|
+
await largeButton.click()
|
|
131
|
+
await expect(sizeText).toContainText('large')
|
|
132
|
+
await page.waitForTimeout(300)
|
|
133
|
+
|
|
134
|
+
// Get large frame height - should be even larger
|
|
135
|
+
const largeBox = await frame.boundingBox()
|
|
136
|
+
const largeHeight = largeBox?.height ?? 0
|
|
137
|
+
expect(largeHeight).toBeGreaterThan(mediumHeight)
|
|
138
|
+
|
|
139
|
+
// Change back to small
|
|
140
|
+
await smallButton.click()
|
|
141
|
+
await expect(sizeText).toContainText('small')
|
|
142
|
+
await page.waitForTimeout(300)
|
|
143
|
+
|
|
144
|
+
// Close the sheet - this is the key test for the white flash fix
|
|
145
|
+
// The sheet should close from its current height without flashing to full viewport
|
|
146
|
+
await closeButton.click()
|
|
147
|
+
await page.waitForTimeout(500)
|
|
148
|
+
|
|
149
|
+
// Sheet should be closed
|
|
150
|
+
await expect(frame).not.toBeInViewport({ ratio: 0.5 })
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
test('sheet closes without white flash - frame height stays stable during close', async ({
|
|
154
|
+
page,
|
|
155
|
+
}) => {
|
|
156
|
+
const trigger = page.getByTestId('standalone-fit-trigger')
|
|
157
|
+
const frame = page.getByTestId('standalone-fit-frame')
|
|
158
|
+
const closeButton = page.getByTestId('standalone-fit-close')
|
|
159
|
+
|
|
160
|
+
// Open the sheet
|
|
161
|
+
await trigger.click()
|
|
162
|
+
await expect(frame).toBeVisible({ timeout: 5000 })
|
|
163
|
+
|
|
164
|
+
// Get the frame height when open
|
|
165
|
+
const openBox = await frame.boundingBox()
|
|
166
|
+
const openHeight = openBox?.height ?? 0
|
|
167
|
+
|
|
168
|
+
// The height should be reasonable (not full viewport)
|
|
169
|
+
// For a fit mode sheet with minimal content, it should be less than half viewport
|
|
170
|
+
const viewportSize = page.viewportSize()
|
|
171
|
+
const viewportHeight = viewportSize?.height ?? 768
|
|
172
|
+
expect(openHeight).toBeLessThan(viewportHeight * 0.6)
|
|
173
|
+
|
|
174
|
+
// Close the sheet and check that height doesn't spike
|
|
175
|
+
await closeButton.click()
|
|
176
|
+
|
|
177
|
+
// Monitor frame height during close animation
|
|
178
|
+
// The fix prevents the frame from expanding to full viewport during close
|
|
179
|
+
let maxHeightDuringClose = openHeight
|
|
180
|
+
for (let i = 0; i < 5; i++) {
|
|
181
|
+
await page.waitForTimeout(100)
|
|
182
|
+
const box = await frame.boundingBox()
|
|
183
|
+
if (box) {
|
|
184
|
+
maxHeightDuringClose = Math.max(maxHeightDuringClose, box.height)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// The max height during close should not be significantly larger than when open
|
|
189
|
+
// This verifies the fix for the white flash issue (expanding to full viewport)
|
|
190
|
+
// Allow some tolerance for animation overshoot
|
|
191
|
+
expect(maxHeightDuringClose).toBeLessThan(openHeight * 1.5)
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test.describe('Adapted Dialog Sheet', () => {
|
|
196
|
+
// TODO: This test is flaky in CI - the adaptation may not trigger reliably at 500px
|
|
197
|
+
// The core functionality is tested by other Sheet tests
|
|
198
|
+
test.skip('dialog adapts to sheet on small screens and closes properly', async ({
|
|
199
|
+
page,
|
|
200
|
+
}) => {
|
|
201
|
+
// Set viewport to small size to trigger adaptation
|
|
202
|
+
await page.setViewportSize({ width: 500, height: 800 })
|
|
203
|
+
await page.reload()
|
|
204
|
+
await page.waitForLoadState('networkidle')
|
|
205
|
+
|
|
206
|
+
const trigger = page.getByTestId('adapted-dialog-trigger')
|
|
207
|
+
const sheetFrame = page.getByTestId('adapted-sheet-frame')
|
|
208
|
+
const dialogContent = page.getByTestId('adapted-dialog-content')
|
|
209
|
+
|
|
210
|
+
await expect(trigger).toBeVisible()
|
|
211
|
+
|
|
212
|
+
// Open - should show as sheet on small viewport
|
|
213
|
+
await trigger.click()
|
|
214
|
+
await page.waitForTimeout(500)
|
|
215
|
+
|
|
216
|
+
// On small viewport, should be adapted to sheet
|
|
217
|
+
const isSheetVisible = await sheetFrame.isVisible()
|
|
218
|
+
const isDialogVisible = await dialogContent.isVisible()
|
|
219
|
+
|
|
220
|
+
// At least one should be visible (either adapted sheet or dialog)
|
|
221
|
+
expect(isSheetVisible || isDialogVisible).toBe(true)
|
|
222
|
+
|
|
223
|
+
// Close via close button (works in both sheet and dialog mode via Adapt.Contents)
|
|
224
|
+
const closeButton = page.getByTestId('adapted-dialog-close')
|
|
225
|
+
await closeButton.click()
|
|
226
|
+
await page.waitForTimeout(500)
|
|
227
|
+
|
|
228
|
+
// Should be closed - sheet frame should not be in viewport
|
|
229
|
+
// Note: dialogContent may still be in DOM but the sheet frame should be off-screen
|
|
230
|
+
await expect(sheetFrame).not.toBeInViewport({ ratio: 0.5 })
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
test('dialog shows as dialog on large screens', async ({ page }) => {
|
|
234
|
+
// Set viewport to large size - no adaptation
|
|
235
|
+
await page.setViewportSize({ width: 1200, height: 800 })
|
|
236
|
+
await page.reload()
|
|
237
|
+
await page.waitForLoadState('networkidle')
|
|
238
|
+
|
|
239
|
+
const trigger = page.getByTestId('adapted-dialog-trigger')
|
|
240
|
+
const dialogContent = page.getByTestId('adapted-dialog-content')
|
|
241
|
+
const closeButton = page.getByTestId('adapted-dialog-close')
|
|
242
|
+
|
|
243
|
+
await expect(trigger).toBeVisible()
|
|
244
|
+
|
|
245
|
+
// Open - should show as dialog on large viewport
|
|
246
|
+
await trigger.click()
|
|
247
|
+
await page.waitForTimeout(500)
|
|
248
|
+
|
|
249
|
+
// Dialog content should be visible
|
|
250
|
+
await expect(dialogContent).toBeVisible()
|
|
251
|
+
|
|
252
|
+
// Close
|
|
253
|
+
await closeButton.click()
|
|
254
|
+
await page.waitForTimeout(500)
|
|
255
|
+
|
|
256
|
+
// Should be closed
|
|
257
|
+
await expect(dialogContent).not.toBeVisible()
|
|
258
|
+
})
|
|
259
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
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: 'ShorthandVariables', type: 'useCase' })
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test(`boxShadow with $variable resolves correctly`, async ({ page }) => {
|
|
11
|
+
const element = page.locator('#boxshadow-var')
|
|
12
|
+
const styles = await getStyles(element)
|
|
13
|
+
|
|
14
|
+
// Should have boxShadow with resolved color (not containing $)
|
|
15
|
+
expect(styles.boxShadow).toBeDefined()
|
|
16
|
+
expect(styles.boxShadow).not.toContain('$')
|
|
17
|
+
expect(styles.boxShadow).toContain('0px 0px 10px')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test(`boxShadow with multiple $variables resolves correctly`, async ({ page }) => {
|
|
21
|
+
const element = page.locator('#boxshadow-multi')
|
|
22
|
+
const styles = await getStyles(element)
|
|
23
|
+
|
|
24
|
+
// Should have boxShadow with multiple shadows, both colors resolved
|
|
25
|
+
expect(styles.boxShadow).toBeDefined()
|
|
26
|
+
expect(styles.boxShadow).not.toContain('$')
|
|
27
|
+
expect(styles.boxShadow).toContain(',') // Multiple shadows separated by comma
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test(`border with $variable resolves correctly`, async ({ page }) => {
|
|
31
|
+
const element = page.locator('#border-var')
|
|
32
|
+
const styles = await getStyles(element)
|
|
33
|
+
|
|
34
|
+
// border expands to individual props, check one of them
|
|
35
|
+
expect(styles.borderTopColor || styles.borderColor).toBeDefined()
|
|
36
|
+
expect(styles.borderTopWidth || styles.borderWidth).toBeDefined()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test(`boxShadow without variables passes through unchanged`, async ({ page }) => {
|
|
40
|
+
const element = page.locator('#boxshadow-plain')
|
|
41
|
+
const styles = await getStyles(element)
|
|
42
|
+
|
|
43
|
+
expect(styles.boxShadow).toBe('rgba(0, 0, 0, 0.2) 0px 0px 10px 0px')
|
|
44
|
+
})
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
import { getStyles } from './utils'
|
|
4
|
+
|
|
5
|
+
test.beforeEach(async ({ page }) => {
|
|
6
|
+
await setupPage(page, { name: 'SpinnerCustomColors', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test('custom color tokens are applied to spinners', async ({ page }) => {
|
|
10
|
+
// Test custom red spinner - check the circle element's stroke
|
|
11
|
+
const redSpinnerStyle = page.locator('#spinner-custom-red circle').first()
|
|
12
|
+
const redSpinnerStroke = (await getStyles(redSpinnerStyle)).stroke
|
|
13
|
+
expect(redSpinnerStroke).toBe('rgb(255, 0, 0)')
|
|
14
|
+
|
|
15
|
+
// Test custom blue spinner
|
|
16
|
+
const blueSpinnerStyle = page.locator('#spinner-custom-blue circle').first()
|
|
17
|
+
const blueSpinnerStroke = (await getStyles(blueSpinnerStyle)).stroke
|
|
18
|
+
expect(blueSpinnerStroke).toBe('rgb(0, 0, 255)')
|
|
19
|
+
|
|
20
|
+
// Test custom green spinner
|
|
21
|
+
const greenSpinnerStyle = page.locator('#spinner-custom-green circle').first()
|
|
22
|
+
const greenSpinnerStroke = (await getStyles(greenSpinnerStyle)).stroke
|
|
23
|
+
expect(greenSpinnerStroke).toBe('rgb(0, 255, 0)')
|
|
24
|
+
|
|
25
|
+
// Test testsomethingdifferent custom color
|
|
26
|
+
const testDifferentStyle = page.locator('#spinner-test-different circle').first()
|
|
27
|
+
const testDifferentStroke = (await getStyles(testDifferentStyle)).stroke
|
|
28
|
+
expect(testDifferentStroke).toBe('rgb(255, 0, 0)') // testsomethingdifferent is also red (#ff0000)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('custom color tokens are available in themes', async ({ page }) => {
|
|
32
|
+
// Verify that custom colors are used through CSS variables
|
|
33
|
+
const customColorVariables = await page.evaluate(() => {
|
|
34
|
+
// Check that the CSS variables exist and have correct values
|
|
35
|
+
const rootStyles = window.getComputedStyle(document.documentElement)
|
|
36
|
+
return {
|
|
37
|
+
customRed: rootStyles.getPropertyValue('--c-color-customRed').trim(),
|
|
38
|
+
customBlue: rootStyles.getPropertyValue('--c-color-customBlue').trim(),
|
|
39
|
+
customGreen: rootStyles.getPropertyValue('--c-color-customGreen').trim(),
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// Verify CSS variables exist
|
|
44
|
+
expect(customColorVariables.customRed).toBe('#ff0000')
|
|
45
|
+
expect(customColorVariables.customBlue).toBe('#0000ff')
|
|
46
|
+
expect(customColorVariables.customGreen).toBe('#00ff00')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('custom color tokens have correct CSS variables', async ({ page }) => {
|
|
50
|
+
// Check that CSS variables are created for custom colors
|
|
51
|
+
const cssVariables = await page.evaluate(() => {
|
|
52
|
+
const rootStyles = window.getComputedStyle(document.documentElement)
|
|
53
|
+
return {
|
|
54
|
+
customRed: rootStyles.getPropertyValue('--c-color-customRed').trim(),
|
|
55
|
+
customBlue: rootStyles.getPropertyValue('--c-color-customBlue').trim(),
|
|
56
|
+
customGreen: rootStyles.getPropertyValue('--c-color-customGreen').trim(),
|
|
57
|
+
testDifferent: rootStyles
|
|
58
|
+
.getPropertyValue('--c-color-testsomethingdifferent')
|
|
59
|
+
.trim(),
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
expect(cssVariables.customRed).toBe('#ff0000')
|
|
64
|
+
expect(cssVariables.customBlue).toBe('#0000ff')
|
|
65
|
+
expect(cssVariables.customGreen).toBe('#00ff00')
|
|
66
|
+
expect(cssVariables.testDifferent).toBe('#ff0000')
|
|
67
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
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: 'StackZIndex', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
// find the portal wrapper's z-index by looking for the ancestor with
|
|
10
|
+
// position:fixed + inline z-index (portal wrappers use inline styles)
|
|
11
|
+
function makeGetZIndexOf(page: any) {
|
|
12
|
+
return async function getZIndexOf(selector: string) {
|
|
13
|
+
return await page.locator(selector).evaluate((el: Element) => {
|
|
14
|
+
let current: Element | null = el
|
|
15
|
+
while (current && current instanceof HTMLElement) {
|
|
16
|
+
if (current.style.position === 'fixed' && current.style.zIndex) {
|
|
17
|
+
return Number.parseInt(current.style.zIndex, 10)
|
|
18
|
+
}
|
|
19
|
+
current = current.parentElement
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`no portal z-index found`)
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
test(`dialogs and portals stack their z-index automatically`, async ({ page }) => {
|
|
27
|
+
const getZIndexOf = makeGetZIndexOf(page)
|
|
28
|
+
|
|
29
|
+
const [a, b, c] = await Promise.all([
|
|
30
|
+
getZIndexOf('#bottom-popover'),
|
|
31
|
+
getZIndexOf('#middle-dialog'),
|
|
32
|
+
getZIndexOf('#top-popover'),
|
|
33
|
+
])
|
|
34
|
+
|
|
35
|
+
expect(c).toBeGreaterThan(b)
|
|
36
|
+
expect(b).toBeGreaterThan(a)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test(`harcoded z-index overrides stacking z-index`, async ({ page }) => {
|
|
40
|
+
const getZIndexOf = makeGetZIndexOf(page)
|
|
41
|
+
|
|
42
|
+
const [a, b, c] = await Promise.all([
|
|
43
|
+
getZIndexOf('#hardcoded-popover'),
|
|
44
|
+
getZIndexOf('#hardcoded-dialog'),
|
|
45
|
+
getZIndexOf('#above-hardcoded-dialog'),
|
|
46
|
+
])
|
|
47
|
+
|
|
48
|
+
expect(a).toBe(200_000)
|
|
49
|
+
expect(b).toBe(300_000)
|
|
50
|
+
expect(c).toBe(300_001)
|
|
51
|
+
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Performance profiling test for the StressPage.
|
|
6
|
+
*
|
|
7
|
+
* Measures render time of a diverse page with ~200+ Hanzo GUI components.
|
|
8
|
+
* Captures both wall-clock render time (performance.mark/measure) and
|
|
9
|
+
* internal @hanzogui/timer breakdown (getSplitStyles, createComponent checkpoints).
|
|
10
|
+
*
|
|
11
|
+
* Run:
|
|
12
|
+
* npx playwright test tests/StressPagePerf.test.tsx --project=default
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const RUNS = 10
|
|
16
|
+
|
|
17
|
+
test('StressPage render profiling', async ({ page }) => {
|
|
18
|
+
const times: number[] = []
|
|
19
|
+
let lastBreakdown: Record<string, number> | null = null
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < RUNS; i++) {
|
|
22
|
+
await setupPage(page, {
|
|
23
|
+
name: 'StressPage',
|
|
24
|
+
type: 'useCase',
|
|
25
|
+
searchParams: { profile: 'true' },
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
await page.waitForFunction(() => (window as any).__PERF_RESULT__, {
|
|
29
|
+
timeout: 10_000,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const result = await page.evaluate(() => (window as any).__PERF_RESULT__)
|
|
33
|
+
times.push(result.renderMs)
|
|
34
|
+
if (result.breakdown) {
|
|
35
|
+
lastBreakdown = result.breakdown
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const sorted = [...times].sort((a, b) => a - b)
|
|
40
|
+
const median = sorted[Math.floor(sorted.length / 2)]
|
|
41
|
+
const mean = Math.round((times.reduce((a, b) => a + b, 0) / times.length) * 10) / 10
|
|
42
|
+
const min = sorted[0]
|
|
43
|
+
const max = sorted[sorted.length - 1]
|
|
44
|
+
const trimmed = sorted.slice(1, -1)
|
|
45
|
+
const trimmedMean =
|
|
46
|
+
Math.round((trimmed.reduce((a, b) => a + b, 0) / trimmed.length) * 10) / 10
|
|
47
|
+
|
|
48
|
+
console.log(`\n=== StressPage Render Profile (${RUNS} runs) ===`)
|
|
49
|
+
console.log(` All: ${times.map((t) => t.toFixed(1) + 'ms').join(', ')}`)
|
|
50
|
+
console.log(` Mean: ${mean}ms | Trimmed Mean: ${trimmedMean}ms | Median: ${median}ms`)
|
|
51
|
+
console.log(` Min: ${min}ms | Max: ${max}ms`)
|
|
52
|
+
|
|
53
|
+
if (lastBreakdown) {
|
|
54
|
+
console.log(`\n --- Internal Breakdown (last run) ---`)
|
|
55
|
+
let propTotal = 0
|
|
56
|
+
const entries = Object.entries(lastBreakdown).filter(([k]) => !k.endsWith('(ignore)'))
|
|
57
|
+
const phases: [string, number][] = []
|
|
58
|
+
for (const [label, totalMs] of entries) {
|
|
59
|
+
if (label.startsWith('before-prop-')) {
|
|
60
|
+
propTotal += totalMs
|
|
61
|
+
} else {
|
|
62
|
+
phases.push([label, totalMs])
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
phases.push(['before-prop-* (all props)', propTotal])
|
|
66
|
+
phases.sort((a, b) => b[1] - a[1])
|
|
67
|
+
for (const [label, totalMs] of phases) {
|
|
68
|
+
if (totalMs < 0.05) continue
|
|
69
|
+
console.log(` ${label.padStart(35)} | ${totalMs.toFixed(1)}ms`)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log(`================================================\n`)
|
|
74
|
+
|
|
75
|
+
expect(median).toBeGreaterThan(0)
|
|
76
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
import { setupPage } from './test-utils'
|
|
3
|
+
|
|
4
|
+
test.beforeEach(async ({ page }) => {
|
|
5
|
+
await setupPage(page, { name: 'StylePlatform', type: 'useCase' })
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test(`styles: $platform-web styles work`, async ({ page }) => {
|
|
9
|
+
const view = page.locator('#style-platform')
|
|
10
|
+
|
|
11
|
+
const styles = await view.evaluate((el) => {
|
|
12
|
+
return window.getComputedStyle(el)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
expect(styles.marginTop).toBe(`10px`)
|
|
16
|
+
expect(styles.marginBottom).toBe(`10px`)
|
|
17
|
+
expect(styles.backgroundColor).toBe(`rgb(255, 0, 0)`)
|
|
18
|
+
expect(styles.overflowY).toBe(`scroll`)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test(`styles: $platform-web hoverStyle works`, async ({ page }) => {
|
|
22
|
+
const view = page.locator('#style-platform-hover')
|
|
23
|
+
|
|
24
|
+
// Before hover: should be blue (base backgroundColor)
|
|
25
|
+
const baseStyles = await view.evaluate((el) => {
|
|
26
|
+
return window.getComputedStyle(el).backgroundColor
|
|
27
|
+
})
|
|
28
|
+
expect(baseStyles).toBe(`rgb(0, 0, 255)`)
|
|
29
|
+
|
|
30
|
+
// Hover: should be green ($platform-web hoverStyle overrides base hoverStyle)
|
|
31
|
+
await view.hover()
|
|
32
|
+
await page.waitForTimeout(100)
|
|
33
|
+
|
|
34
|
+
const hoverStyles = await view.evaluate((el) => {
|
|
35
|
+
return window.getComputedStyle(el).backgroundColor
|
|
36
|
+
})
|
|
37
|
+
expect(hoverStyles).toBe(`rgb(0, 128, 0)`)
|
|
38
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
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: 'StyleProp', type: 'useCase' })
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test(`style prop flattens`, async ({ page }) => {
|
|
11
|
+
expect((await getStyles(page.getByTestId('style-prop').first())).background).toBe(
|
|
12
|
+
`rgba(0, 0, 0, 0) radial-gradient(rgb(143, 143, 143), rgba(0, 0, 0, 0) 70%) repeat scroll 0% 0% / auto padding-box border-box`
|
|
13
|
+
)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test(`className prop flattens`, async ({ page }) => {
|
|
17
|
+
expect((await getStyles(page.getByTestId('class-name').first())).backgroundColor).toBe(
|
|
18
|
+
`rgb(255, 0, 0)`
|
|
19
|
+
)
|
|
20
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
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: 'StyledAnchor', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test(`styled anchor passes non-styled attributes through`, async ({ page }) => {
|
|
10
|
+
const anchor = page.getByTestId('test-anchor')
|
|
11
|
+
expect(await anchor.getAttribute('target')).toBe('_blank')
|
|
12
|
+
expect(await anchor.getAttribute('href')).toBe('https://gui.hanzo.ai/test-link')
|
|
13
|
+
|
|
14
|
+
const anchor2 = page.getByTestId('test-anchor2')
|
|
15
|
+
expect(await anchor2.getAttribute('target')).toBe('_blank')
|
|
16
|
+
expect(await anchor2.getAttribute('href')).toBe('https://gui.hanzo.ai/test-link')
|
|
17
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
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: 'StyledButtonTheme', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test(`button + styled + styleable + theme works`, async ({ page }) => {
|
|
10
|
+
const styles = await page.locator('#test').evaluate((el) => {
|
|
11
|
+
return window.getComputedStyle(el)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// Green theme background from themeDev (desaturated green)
|
|
15
|
+
expect(styles.backgroundColor).toBe(`rgb(219, 235, 224)`)
|
|
16
|
+
|
|
17
|
+
const styles2 = await page.locator('#test2').evaluate((el) => {
|
|
18
|
+
return window.getComputedStyle(el)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
expect(styles2.backgroundColor).toBe(`rgb(0, 0, 0)`)
|
|
22
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
|
|
3
|
+
import { setupPage } from './test-utils'
|
|
4
|
+
import { getHoverStyle, getPressStyle } from './utils'
|
|
5
|
+
|
|
6
|
+
test.beforeEach(async ({ page }) => {
|
|
7
|
+
await setupPage(page, { name: 'StyledButtonVariantPseudo', type: 'useCase' })
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test(`hover HOC + variant + pseudos work`, async ({ page }) => {
|
|
11
|
+
const button = page.locator('button#test')
|
|
12
|
+
const hoverStyles = await getHoverStyle(button)
|
|
13
|
+
expect(hoverStyles.backgroundColor).toBe(`rgb(0, 128, 0)`)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test(`press HOC + variant + pseudos work`, async ({ page }) => {
|
|
17
|
+
const button = page.locator('button')
|
|
18
|
+
const pressStyles = await getPressStyle(button, { delay: 3000 })
|
|
19
|
+
expect(pressStyles.backgroundColor).toBe(`rgb(255, 0, 0)`)
|
|
20
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { expect, test } from '@playwright/test'
|
|
2
|
+
|
|
3
|
+
import { setupPage } from './test-utils'
|
|
4
|
+
import { getPressStyle } from './utils'
|
|
5
|
+
|
|
6
|
+
// These tests only run with CSS driver
|
|
7
|
+
test.beforeEach(async ({ page }, testInfo) => {
|
|
8
|
+
const driver = (testInfo.project?.metadata as any)?.animationDriver
|
|
9
|
+
test.skip(driver !== 'css', `skipping for ${driver} driver`)
|
|
10
|
+
|
|
11
|
+
await setupPage(page, { name: 'StyledButtonVariantPseudoMerge', type: 'useCase' })
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test(`pseudo + variant with pseudo should merge`, async ({ page }) => {
|
|
15
|
+
const button = page.locator('button#test')
|
|
16
|
+
const pressStyles = await getPressStyle(button, { delay: 3000 })
|
|
17
|
+
expect(pressStyles.backgroundColor).toBe(`rgb(255, 0, 0)`)
|
|
18
|
+
expect(pressStyles.transform).toBe(`matrix(0.5, 0, 0, 0.5, 0, 0)`)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test(`animation + pseudo + variant with pseudo should merge`, async ({ page }) => {
|
|
22
|
+
const button = page.locator('#animated')
|
|
23
|
+
const pressStyles = await getPressStyle(button, { delay: 3000 })
|
|
24
|
+
expect(pressStyles.backgroundColor).toBe(`rgb(255, 0, 0)`)
|
|
25
|
+
expect(pressStyles.transform).toBe(`matrix(0.5, 0, 0, 0.5, 0, 0)`)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test(`styled without variants HOC of HOC + pseudo`, async ({ page }) => {
|
|
29
|
+
const button = page.locator('#double-styled')
|
|
30
|
+
const pressStyles = await getPressStyle(button, { delay: 3000 })
|
|
31
|
+
expect(pressStyles.backgroundColor).toBe(`rgb(255, 0, 0)`)
|
|
32
|
+
expect(pressStyles.transform).toBe(`matrix(0.5, 0, 0, 0.5, 0, 0)`)
|
|
33
|
+
})
|
|
@@ -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: 'StyledCheckboxTheme', type: 'useCase' })
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
test(`theme passes through .styleable HOC`, async ({ page }) => {
|
|
10
|
+
const styles = await page.locator('button[role=checkbox]').evaluate((el) => {
|
|
11
|
+
return window.getComputedStyle(el)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// Green theme background from themeDev
|
|
15
|
+
expect(styles.backgroundColor).toBe(`rgb(232, 242, 235)`)
|
|
16
|
+
})
|