ViewTransition fixes
Some checks failed
E2E Tests / e2e (push) Has been cancelled
Tests and checks on push / run-checks-and-tests (push) Has been cancelled
Updates translation progress / update-translation-progress-issue (push) Has been cancelled

This commit is contained in:
Kalle
2026-09-27 19:42:18 +03:00
parent 5157272b5e
commit 2f1c971c1e
6 changed files with 25 additions and 42 deletions

View File

@@ -33,7 +33,7 @@ import { inGameNameWithoutDiscriminator } from "~/utils/strings";
import { SENDOUQ_LOOKING_PAGE, TIERS_PAGE, tierImageUrl } from "~/utils/urls";
import {
finishUpdateIfUnmoved,
usePageViewTransitionClass,
usePageViewTransitionClasses,
} from "~/utils/view-transition";
import type {
SQGroup,
@@ -306,12 +306,14 @@ function GroupCardContainer({
isOwnGroup: boolean;
children: React.ReactNode;
}) {
const updateClass = usePageViewTransitionClass("card-update");
const transitionClasses = usePageViewTransitionClasses({
update: "card-update",
});
if (isOwnGroup) return <>{children}</>;
return (
<ViewTransition update={updateClass} onUpdate={finishUpdateIfUnmoved}>
<ViewTransition {...transitionClasses} onUpdate={finishUpdateIfUnmoved}>
{children}
</ViewTransition>
);

View File

@@ -1,20 +0,0 @@
::view-transition-old(root),
.dark::view-transition-old(root) {
animation: none;
animation-fill-mode: both;
z-index: -1;
}
::view-transition-new(root) {
mask: url("./wave.svg") no-repeat;
mask-position: 50% 200%;
mask-size: max(100vw, 200vh);
animation: sweep 1.5s;
animation-fill-mode: both;
}
@keyframes sweep {
to {
mask-position: 50% 0%;
}
}

View File

@@ -31,7 +31,6 @@ import { loader } from "../loaders/settings.server";
import type { SettingsTabSlug } from "../settings-constants";
import { settingsSearchParams } from "../settings-search-params";
import { defaultTab, resolveActiveTab } from "../settings-utils";
import "./settings.global.css";
export { action, loader };

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -26,7 +26,7 @@ import type { MainWeaponId } from "~/modules/in-game-lists/types";
import { navIconUrl } from "~/utils/urls";
import {
finishUpdateIfUnmoved,
usePageViewTransitionClass,
usePageViewTransitionClasses,
} from "~/utils/view-transition";
import {
lookingSchema,
@@ -185,12 +185,14 @@ function LFGGroupCardContainer({
isOwnGroup: boolean;
children: React.ReactNode;
}) {
const updateClass = usePageViewTransitionClass("card-update");
const transitionClasses = usePageViewTransitionClasses({
update: "card-update",
});
if (isOwnGroup) return <>{children}</>;
return (
<ViewTransition update={updateClass} onUpdate={finishUpdateIfUnmoved}>
<ViewTransition {...transitionClasses} onUpdate={finishUpdateIfUnmoved}>
{children}
</ViewTransition>
);

View File

@@ -1,4 +1,4 @@
import type { ViewTransitionInstance } from "react";
import type { ViewTransitionInstance, ViewTransitionProps } from "react";
import * as React from "react";
interface PseudoElement {
@@ -14,6 +14,12 @@ type PseudoElements = Record<
const MEASURED_PROPERTIES = ["transform", "width", "height"] as const;
const NUMBER_PATTERN = /-?\d*\.?\d+/g;
const HOVER_CURSOR_PROPERTY = "--hover-cursor";
const MODAL_OPEN_CLASSES: ViewTransitionClasses = { default: "none" };
type ViewTransitionClasses = Pick<
ViewTransitionProps,
"default" | "enter" | "exit" | "update" | "share"
>;
/** How many modal dialogs are open, provided by the root. */
export const OpenModalsContext = React.createContext<{
@@ -113,7 +119,7 @@ export function useHoverCursorForViewTransitions() {
}, []);
}
/** Counts the calling dialog as an open modal while `isOpen`, see `usePageViewTransitionClass`. */
/** Counts the calling dialog as an open modal while `isOpen`, see `usePageViewTransitionClasses`. */
export function useReportModalOpen(isOpen: boolean) {
const { setCount } = React.useContext(OpenModalsContext);
@@ -125,10 +131,12 @@ export function useReportModalOpen(isOpen: boolean) {
}
/**
* The `<ViewTransition>` class for an element of the page: `"none"` while a modal dialog is open.
* Snapshots paint above the dialog's backdrop, so a transition under it would show the page
* unblurred for a few frames, and there is nothing worth animating under a modal anyway.
* The `<ViewTransition>` classes for an element of the page, every trigger `"none"` while a modal
* dialog is open. Snapshots paint above the dialog's backdrop, so a transition under it would show
* the page unblurred for a few frames, and there is nothing worth animating under a modal anyway.
*/
export function usePageViewTransitionClass(className: string) {
return React.useContext(OpenModalsContext).count > 0 ? "none" : className;
export function usePageViewTransitionClasses(classes: ViewTransitionClasses) {
return React.useContext(OpenModalsContext).count > 0
? MODAL_OPEN_CLASSES
: classes;
}