Page Transitions
Route-based page transition system
Configuration Interface
SsgoiConfig
interface SsgoiConfig {
transitions: Array<{
from: string; // Source route pattern
to: string; // Destination route pattern
transition: SggoiTransition;
symmetric?: boolean; // Auto-generate bidirectional transition
}>;
defaultTransition?: SggoiTransition;
}
Basic Configuration
import { Ssgoi } from "@ssgoi/react";
import { fade, scroll, drill } from "@ssgoi/react/view-transitions";
const config = {
defaultTransition: fade(), // Default transition
transitions: [
{
from: "/",
to: "/about",
transition: scroll({ direction: "up" }),
},
{
from: "/about",
to: "/",
transition: scroll({ direction: "down" }),
},
],
};
export default function Layout({ children }) {
return (
<Ssgoi config={config}>
<div style={{ position: "relative", minHeight: "100vh" }}>
{children}
</div>
</Ssgoi>
);
}
Route Matching Rules
Pattern Types
- Exact Match:
/home→ Matches exactly with/home - Wildcard Suffix:
/products/*→ Matches/products/123 - Full Wildcard:
*→ Matches all routes
Matching Priority
More specific patterns take precedence:
transitions: [
// 1st priority: Exact match
{ from: "/blog/post-1", to: "/blog/post-2", transition: scroll() },
// 2nd priority: Wildcard match
{ from: "/blog/*", to: "/blog/*", transition: fade() },
// 3rd priority: defaultTransition
];
Symmetric Option
Automatically generates bidirectional transitions:
{
from: '/home',
to: '/about',
transition: fade(),
symmetric: true // Automatically generates reverse transition
}
// The above configuration works as follows:
// /home → /about: fade
// /about → /home: fade (auto-generated)
View Transition Structure
View Transition follows the same structure as Element Transition:
interface ViewTransition {
in?: (
element: HTMLElement,
context?: SggoiTransitionContext
) => TransitionConfig;
out?: (
element: HTMLElement,
context?: SggoiTransitionContext
) => TransitionConfig;
}
- out: Applied to from page (exiting page)
- in: Applied to to page (entering page)
Context Object
The scroll difference between the previous page and current page is passed as the second argument to View Transition:
interface SggoiTransitionContext {
scrollOffset: {
x: number; // Scroll X difference between previous and current page
y: number; // Scroll Y difference between previous and current page
};
}
// Example: Scroll-aware transition
const scrollAwareTransition = {
in: (element, context) => {
const { scrollOffset } = context;
return {
prepare: (el) => {
// Start by moving by the scroll difference
el.style.transform = `translateY(${-scrollOffset.y}px)`;
},
tick: (progress) => ({
// Return to original position
transform: `translateY(${-scrollOffset.y * (1 - progress)}px)`,
}),
};
},
};
SsgoiTransition Wrapper
Wrapper component (directive for Angular) that wraps each page:
import { SsgoiTransition } from "@ssgoi/react";
export default function Page() {
return (
<SsgoiTransition id="/page-path">
<PageContent />
</SsgoiTransition>
);
}
ssgoiTransition: Identifier used for route matching- This value is matched against from/to patterns in the config
Operation Flow
- Route Change Detection: Router changes route
- Pattern Matching: Find transition to apply using from/to patterns
- Out Animation: Apply out transition to current page
- Synchronization: Wait for out and in animation preparation
- In Animation: Apply in transition to new page
- Completion: Clean up when both animations complete
Practical Examples
Hierarchical Navigation
const config = {
transitions: [
// List → Detail
{
from: "/products",
to: "/products/*",
transition: drill({ direction: 'enter' }),
symmetric: true, // Auto-handle Detail → List too
},
// Tab navigation
{ from: "/tab1", to: "/tab2", transition: scroll({ direction: "up" }) },
{ from: "/tab2", to: "/tab3", transition: scroll({ direction: "up" }) },
{ from: "/tab3", to: "/tab2", transition: scroll({ direction: "down" }) },
{ from: "/tab2", to: "/tab1", transition: scroll({ direction: "down" }) },
],
};