Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
08e7cae
Add support for chronological and pagination transitions
b1ink0 Jan 8, 2026
f518306
Add options to settings for chronological and pagination transitions
b1ink0 Jan 8, 2026
e1d07ae
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 Jan 8, 2026
0bcdbc1
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 Jan 27, 2026
431e777
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 Feb 25, 2026
d3b4785
Wrap animation stylesheet in media query for reduced motion preference
b1ink0 Feb 25, 2026
f2ce961
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
westonruter Feb 27, 2026
5c43cc2
Apply some static analysis improvements
westonruter Feb 27, 2026
b6dfded
Export pagination_base from PHP
westonruter Feb 27, 2026
772328e
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 Apr 1, 2026
5a22f93
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 Apr 28, 2026
9f38a99
Fix theme support validation
b1ink0 Apr 28, 2026
c8ba51b
Add support for animation duration in additional transition animation
b1ink0 May 12, 2026
b11ae36
Update types and add checks for animation config
b1ink0 May 12, 2026
8bc1d86
Add separate checkbox for enabling chronological pagination transition
b1ink0 May 19, 2026
9741eb3
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 May 19, 2026
3490e2d
Merge branch 'trunk' into enhancement/add-chronological-pagination-tr…
b1ink0 Sep 2, 2026
161d576
Decouple chronological and pagination animation settings from the def…
b1ink0 Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions plugins/view-transitions/includes/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@
*/
function plvt_get_view_transition_animation_labels(): array {
return array(
'fade' => _x( 'Fade (default)', 'animation label', 'view-transitions' ),
'slide-from-right' => _x( 'Slide (from right)', 'animation label', 'view-transitions' ),
'slide-from-left' => _x( 'Slide (from left)', 'animation label', 'view-transitions' ),
'slide-from-bottom' => _x( 'Slide (from bottom)', 'animation label', 'view-transitions' ),
'slide-from-top' => _x( 'Slide (from top)', 'animation label', 'view-transitions' ),
'swipe-from-right' => _x( 'Swipe (from right)', 'animation label', 'view-transitions' ),
'swipe-from-left' => _x( 'Swipe (from left)', 'animation label', 'view-transitions' ),
'swipe-from-bottom' => _x( 'Swipe (from bottom)', 'animation label', 'view-transitions' ),
'swipe-from-top' => _x( 'Swipe (from top)', 'animation label', 'view-transitions' ),
'wipe-from-right' => _x( 'Wipe (from right)', 'animation label', 'view-transitions' ),
'wipe-from-left' => _x( 'Wipe (from left)', 'animation label', 'view-transitions' ),
'wipe-from-bottom' => _x( 'Wipe (from bottom)', 'animation label', 'view-transitions' ),
'wipe-from-top' => _x( 'Wipe (from top)', 'animation label', 'view-transitions' ),
'fade' => _x( 'Fade (default)', 'animation label', 'view-transitions' ),
'slide-from-right' => _x( 'Slide (from right)', 'animation label', 'view-transitions' ),
'slide-from-left' => _x( 'Slide (from left)', 'animation label', 'view-transitions' ),
'slide-from-bottom' => _x( 'Slide (from bottom)', 'animation label', 'view-transitions' ),
'slide-from-top' => _x( 'Slide (from top)', 'animation label', 'view-transitions' ),
'slide-chronological-pagination' => _x( 'Slide (Chronological and Pagination)', 'animation label', 'view-transitions' ),
'swipe-from-right' => _x( 'Swipe (from right)', 'animation label', 'view-transitions' ),
'swipe-from-left' => _x( 'Swipe (from left)', 'animation label', 'view-transitions' ),
'swipe-from-bottom' => _x( 'Swipe (from bottom)', 'animation label', 'view-transitions' ),
'swipe-from-top' => _x( 'Swipe (from top)', 'animation label', 'view-transitions' ),
'swipe-chronological-pagination' => _x( 'Swipe (Chronological and Pagination)', 'animation label', 'view-transitions' ),
'wipe-from-right' => _x( 'Wipe (from right)', 'animation label', 'view-transitions' ),
'wipe-from-left' => _x( 'Wipe (from left)', 'animation label', 'view-transitions' ),
'wipe-from-bottom' => _x( 'Wipe (from bottom)', 'animation label', 'view-transitions' ),
'wipe-from-top' => _x( 'Wipe (from top)', 'animation label', 'view-transitions' ),
'wipe-chronological-pagination' => _x( 'Wipe (Chronological and Pagination)', 'animation label', 'view-transitions' ),
);
}

Expand Down Expand Up @@ -231,7 +234,22 @@ function plvt_apply_settings_to_theme_support(): void {
// Apply the settings.
$args['default-animation'] = $options['default_transition_animation'];
$args['default-animation-duration'] = absint( $options['default_transition_animation_duration'] );
$selector_options = array(

// Automatically enable chronological and pagination animations for special animation options.
$chronological_pagination_animations = array(
'slide-chronological-pagination' => 'slide',
'swipe-chronological-pagination' => 'swipe',
'wipe-chronological-pagination' => 'wipe',
);
if ( isset( $chronological_pagination_animations[ $args['default-animation'] ] ) ) {
$base_animation = $chronological_pagination_animations[ $args['default-animation'] ];
$args['chronological-forwards-animation'] = $base_animation . '-from-right';
$args['chronological-backwards-animation'] = $base_animation . '-from-left';
$args['pagination-forwards-animation'] = $base_animation . '-from-right';
$args['pagination-backwards-animation'] = $base_animation . '-from-left';
}

Copilot AI Jan 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the special *-chronological-pagination option is selected, $args['default-animation'] remains set to that value, but it is not a registered animation slug/alias in the animation registry. As a result, the default transition falls back to the browser default (fade) instead of the intended slide/swipe/wipe. Map $args['default-animation'] to a real registry alias/slug (e.g. the base animation or a concrete direction) when enabling these special options.

Copilot uses AI. Check for mistakes.

$selector_options = array(
'global' => array(
'header_selector' => 'header',
'main_selector' => 'main',
Expand Down
123 changes: 116 additions & 7 deletions plugins/view-transitions/includes/theme.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,22 @@ function plvt_sanitize_view_transitions_theme_support(): void {
$args = $_wp_theme_features['view-transitions'];

$defaults = array(
'post-selector' => '.wp-block-post.post, article.post, body.single main',
'global-transition-names' => array(
'post-selector' => '.wp-block-post.post, article.post, body.single main',
'global-transition-names' => array(
'header' => 'header',
'main' => 'main',
),
'post-transition-names' => array(
'post-transition-names' => array(
'.wp-block-post-title, .entry-title' => 'post-title',
'.wp-post-image' => 'post-thumbnail',
'.wp-block-post-content, .entry-content' => 'post-content',
),
'default-animation' => 'fade',
'default-animation-duration' => 400,
'default-animation' => 'fade',
'default-animation-duration' => 400,
'chronological-forwards-animation' => false,
'chronological-backwards-animation' => false,
'pagination-forwards-animation' => false,
'pagination-backwards-animation' => false,
);

// If no specific `$args` were provided, simply use the defaults.
Expand All @@ -102,8 +106,21 @@ function plvt_sanitize_view_transitions_theme_support(): void {
if ( ! is_array( $args['post-transition-names'] ) ) {
$args['post-transition-names'] = array();
}
}

// If specific transition animations match the default animations, they are irrelevant.
if ( $args['chronological-forwards-animation'] === $args['default-animation'] ) {
$args['chronological-forwards-animation'] = false;
}
if ( $args['chronological-backwards-animation'] === $args['default-animation'] ) {
$args['chronological-backwards-animation'] = false;
}
if ( $args['pagination-forwards-animation'] === $args['default-animation'] ) {
$args['pagination-forwards-animation'] = false;
}
if ( $args['pagination-backwards-animation'] === $args['default-animation'] ) {
$args['pagination-backwards-animation'] = false;
}
}
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$_wp_theme_features['view-transitions'] = $args;
}
Expand Down Expand Up @@ -324,7 +341,11 @@ function plvt_load_view_transitions(): void {
*/
if (
( ! is_array( $theme_support['global-transition-names'] ) || count( $theme_support['global-transition-names'] ) === 0 ) &&
( ! is_array( $theme_support['post-transition-names'] ) || count( $theme_support['post-transition-names'] ) === 0 )
( ! is_array( $theme_support['post-transition-names'] ) || count( $theme_support['post-transition-names'] ) === 0 ) &&
! (bool) $theme_support['chronological-forwards-animation'] &&
! (bool) $theme_support['chronological-backwards-animation'] &&
! (bool) $theme_support['pagination-forwards-animation'] &&
! (bool) $theme_support['pagination-backwards-animation']
) {
return;
}
Expand All @@ -336,6 +357,34 @@ function plvt_load_view_transitions(): void {
),
);

$additional_transition_types = array(
'chronological-forwards',
'chronological-backwards',
'pagination-forwards',
'pagination-backwards',
);

Comment on lines +381 to +387

Copilot AI Jan 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior is introduced for additional transition types (chronological/pagination) and CSS scoping, but the existing PHP unit tests in plugins/view-transitions/tests/test-theme.php don’t cover any of this (e.g. ensuring disabled types remain disabled, and enabled types enqueue scoped CSS). Please add/update tests around the additional transition type handling to prevent regressions.

Copilot uses AI. Check for mistakes.
foreach ( $additional_transition_types as $transition_type ) {
if ( isset( $theme_support[ $transition_type . '-animation' ] ) ) {
$additional_animation_args = isset( $theme_support[ $transition_type . '-animation-args' ] ) ? (array) $theme_support[ $transition_type . '-animation-args' ] : array();
$additional_animation_stylesheet = $animation_registry->get_animation_stylesheet( $theme_support[ $transition_type . '-animation' ], $additional_animation_args );
if ( '' !== $additional_animation_stylesheet ) {
wp_add_inline_style(
'plvt-view-transitions',
plvt_scope_animation_stylesheet_to_transition_type( $additional_animation_stylesheet, $transition_type )
Comment thread
b1ink0 marked this conversation as resolved.
Outdated
);
Comment thread
b1ink0 marked this conversation as resolved.
Outdated
}

$animations_js_config[ $transition_type ] = array(
'useGlobalTransitionNames' => $animation_registry->use_animation_global_transition_names( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ),
'usePostTransitionNames' => $animation_registry->use_animation_post_transition_names( $theme_support[ $transition_type . '-animation' ], $additional_animation_args ),
'targetName' => isset( $additional_animation_args['target-name'] ) ? $additional_animation_args['target-name'] : '*', // Special argument.
);
} else {
$animations_js_config[ $transition_type ] = false;
}
}
Comment thread
b1ink0 marked this conversation as resolved.

$config = array(
'postSelector' => $theme_support['post-selector'],
'globalTransitionNames' => $theme_support['global-transition-names'],
Expand Down Expand Up @@ -389,3 +438,63 @@ function plvt_inject_animation_duration( string $css, int $animation_duration ):

return $css;
}

/**
* Scopes the given view transition animation CSS to apply only to a specific transition type.
*
* @since n.e.x.t
Comment thread
westonruter marked this conversation as resolved.
* @access private
*
* @param string $css Animation stylesheet as inline CSS.
* @param string $transition_type Transition type to scope the CSS to.
* @return string Scoped animation stylesheet.
*/
function plvt_scope_animation_stylesheet_to_transition_type( string $css, string $transition_type ): string {
$indent = static function ( string $input, $indent_tabs = 1 ): string {
return implode(
"\n",
array_map(
static function ( string $line ) use ( $indent_tabs ): string {
return str_repeat( "\t", $indent_tabs ) . $line;
},
explode( "\n", $input )
)
);
};

// This is very fragile, but it works well enough for now. TODO: Find a better solution to scope the CSS selectors.
if ( (bool) preg_match_all( '/(\s*)([^{}]+)\{[^{}]*?\}/m', $css, $matches ) ) {
// Wrap all `::view-transition-*` selectors to scope them to the transition type.
$view_transition_rule_pattern = '/::view-transition-/';

foreach ( $matches[0] as $index => $match ) {
$rule = $match;
$rule_name = $matches[2][ $index ];
if ( (bool) preg_match( $view_transition_rule_pattern, $rule_name ) ) {
$rule_whitespace = $matches[1][ $index ];
$prefixed_rule_name = preg_replace( $view_transition_rule_pattern, '&\0', $rule_name );
if ( null === $prefixed_rule_name ) {
continue;
}

$rule = str_replace( $rule_name, $prefixed_rule_name, $rule );

if ( str_contains( $rule, "\n" ) ) { // Non-minified.
$rule = $rule_whitespace .
"html:active-view-transition-type({$transition_type}) {\n" .
$indent( substr( $rule, strlen( $rule_whitespace ) ), 1 ) .
"\n}";
} else { // Minified.
$rule = $rule_whitespace .
"html:active-view-transition-type({$transition_type}){" .
substr( $rule, strlen( $rule_whitespace ) ) .
'}';
}

// Replace the original rule with the wrapped/scoped one.
$css = str_replace( $match, $rule, $css );
}
}
}
return $css;
}
4 changes: 4 additions & 0 deletions plugins/view-transitions/js/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export type InitViewTransitionsFunction = (
config: ViewTransitionsConfig
) => void;

export type NavigationHistoryEntry = {
url: string;
};
Comment thread
b1ink0 marked this conversation as resolved.

declare global {
interface Window {
plvtInitViewTransitions?: InitViewTransitionsFunction;
Expand Down
Loading
Loading