Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Back to top block #50600

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
fa9ccad
Add back to top block
carolinan May 12, 2023
fee0a39
Add fixtures
carolinan May 13, 2023
1cc688a
Update index.php
carolinan May 13, 2023
7ee4f4b
Update index.php
carolinan May 13, 2023
382991d
Merge branch 'trunk' into add/back-to-top
carolinan May 15, 2023
3d2cf38
Add a viewScript that moves focus
carolinan May 15, 2023
615cc8c
Add aria-label to the RichText, and change the capitalization of "top"
carolinan May 19, 2023
9875eaf
Merge branch 'trunk' into add/back-to-top
carolinan May 19, 2023
f5ac6fc
Remove the viewscript and a div with the target id to the body.
carolinan May 24, 2023
7fe0fbd
fix a small typo
carolinan May 24, 2023
c84f3a9
Block themes: Only add the target id if the block exists on the page
carolinan May 24, 2023
27239b4
Update index.php
carolinan May 24, 2023
2b51162
Update index.php
carolinan May 24, 2023
ba1eebf
Try to use the JavaScript file as a fallback for classic themes
carolinan May 29, 2023
a729dcd
Merge branch 'trunk' into add/back-to-top
carolinan Jun 14, 2023
b972cf7
Try moving the JavaScript fallback
carolinan Jun 16, 2023
f3b89ea
Merge branch 'trunk' into add/back-to-top
carolinan Jun 26, 2023
63a302b
Update apiVersion from 2 to 3.
carolinan Jun 26, 2023
ae9abe0
Merge branch 'trunk' into add/back-to-top
carolinan Jul 11, 2023
583b2b3
Merge branch 'trunk' into add/back-to-top
carolinan Jul 21, 2023
2c2fdc3
Merge branch 'trunk' into add/back-to-top
carolinan Aug 7, 2023
7c2c707
Merge branch 'trunk' into add/back-to-top
carolinan Aug 18, 2023
9f83e85
rename fallback function
carolinan Aug 18, 2023
60697c5
Merge branch 'trunk' into add/back-to-top
carolinan Sep 26, 2023
8698f9c
Merge branch 'trunk' into add/back-to-top
carolinan Oct 11, 2023
69f1ca1
Add more focusable elements to the view script. Update doc blocks.
carolinan Oct 11, 2023
8ba2e3f
Fix CS spacing issue
carolinan Oct 11, 2023
3184017
Merge branch 'trunk' into add/back-to-top
carolinan Oct 25, 2023
f632327
Merge branch 'trunk' into add/back-to-top
carolinan Nov 17, 2023
91bd787
Merge branch 'trunk' into add/back-to-top
carolinan Nov 23, 2023
de043f0
Merge branch 'trunk' into add/back-to-top
carolinan Nov 24, 2023
6c5fd03
Merge branch 'trunk' into add/back-to-top
carolinan Jan 2, 2024
2b1a56d
Merge branch 'trunk' into add/back-to-top
carolinan Jan 25, 2024
5b5cc2b
Merge branch 'trunk' into add/back-to-top
carolinan Feb 14, 2024
f55ceff
Merge branch 'trunk' into add/back-to-top
carolinan Feb 22, 2024
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
9 changes: 9 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ Add a user’s avatar. ([Source](https://github.com/WordPress/gutenberg/tree/tru
- **Supports:** align, color (~~background~~, ~~text~~), interactivity (clientNavigation), spacing (margin, padding), ~~alignWide~~, ~~html~~
- **Attributes:** isLink, linkTarget, size, userId

## Back to top

A link that takes you back to the top. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/back-to-top))

- **Name:** core/back-to-top
- **Category:** design
- **Supports:** ~~html~~
- **Attributes:** text

## Pattern

Reuse this design across your site. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/block))
Expand Down
2 changes: 2 additions & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function gutenberg_reregister_core_block_types() {
__DIR__ . '/../build/block-library/blocks/' => array(
'block_folders' => array(
'audio',
'back-to-top',
'button',
'buttons',
'freeform',
Expand Down Expand Up @@ -49,6 +50,7 @@ function gutenberg_reregister_core_block_types() {
'block_names' => array(
'archives.php' => 'core/archives',
'avatar.php' => 'core/avatar',
'back-to-top.php' => 'core/back-to-top',
'block.php' => 'core/block',
'calendar.php' => 'core/calendar',
'categories.php' => 'core/categories',
Expand Down
18 changes: 18 additions & 0 deletions packages/block-library/src/back-to-top/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "core/back-to-top",
"title": "Back to top",
"category": "design",
"description": "A link that takes you back to the top.",
"keywords": [ "top", "skip link" ],
"textdomain": "default",
"attributes": {
"text": {
"type": "string"
}
},
"supports": {
"html": false
}
}
23 changes: 23 additions & 0 deletions packages/block-library/src/back-to-top/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';

export default function BackToTopEdit( { attributes, setAttributes } ) {
const { text } = attributes;
return (
<p { ...useBlockProps() }>
<RichText
carolinan marked this conversation as resolved.
Show resolved Hide resolved
tagName="a"
href="#wp-back-to-top"
aria-label={ __( 'Back to top link text' ) }
value={ text ? text : __( 'Back to top' ) }
withoutInteractiveFormatting={ true }
onChange={ ( newLinkText ) =>
setAttributes( { text: newLinkText } )
}
/>
</p>
);
}
20 changes: 20 additions & 0 deletions packages/block-library/src/back-to-top/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* WordPress dependencies
*/
import { arrowUp as icon } from '@wordpress/icons';

/**
* Internal dependencies
*/
import initBlock from '../utils/init-block';
import edit from './edit';
import metadata from './block.json';

const { name } = metadata;
export { metadata, name };
export const settings = {
icon,
edit,
};

export const init = () => initBlock( { name, metadata, settings } );
89 changes: 89 additions & 0 deletions packages/block-library/src/back-to-top/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
/**
* Server-side rendering of the `core/back-to-top` block.
*
* @package WordPress
*/

/**
* Renders the `core/back-to-top` block on the server.
*
* @param array $attributes Block attributes.
* @return string Return the back to top link.
*/
function render_block_core_back_to_top( $attributes ) {
$link_text = isset( $attributes['text'] ) ? $attributes['text'] : __( 'Back to top' );
$wrapper_attributes = get_block_wrapper_attributes();

block_core_back_to_top_classic_fallback();

return sprintf(
'<p %1$s><a href="#wp-back-to-top">%2$s</a></p>',
$wrapper_attributes,
wp_kses_post( $link_text )
);
}

/**
* Registers the `core/back_to_top` block on the server.
*/
function register_block_core_back_to_top() {
register_block_type_from_metadata(
__DIR__ . '/back-to-top',
array(
'render_callback' => 'render_block_core_back_to_top',
)
);
}
add_action( 'init', 'register_block_core_back_to_top' );

/**
* Adds the target id 'wp-back-to-top' to the top of the page, so that focus can be moved.
* Block themes: Add the target id if the back to top block exists on the page.
* Classic themes with 'wp_body_open()': Always add the target id.
*/
function block_core_back_to_top_target() {
echo '<div id="wp-back-to-top"></div>';
}
if ( wp_is_block_theme() ) {
add_filter(
'render_block',
function ( $html, $block ) {
if ( 'core/back-to-top' === $block['blockName'] ) {
add_action( 'wp_body_open', 'block_core_back_to_top_target' );
}
return $html;
},
10,
2
);
} else {
add_action( 'wp_body_open', 'block_core_back_to_top_target' );
}

/**
* For classic themes that do not use `wp_body_open()`,
* view.js is needed to move focus to the first focusable element on the top of the page.
*/
function block_core_back_to_top_classic_fallback() {
if ( ! wp_is_block_theme() && 0 === did_action( 'wp_body_open' ) ) {
// If the Gutenberg plugin is active, use the script from the plugin.
if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
wp_enqueue_script(
'wp-block-library-back-to-top-fallback',
plugins_url( 'back-to-top/view.min.js', __FILE__ ),
array(),
filemtime( plugin_dir_path( __FILE__ ) . 'back-to-top/view.min.js' ),
true
);
} else {
wp_enqueue_script(
'wp-block-library-back-to-top-fallback',
includes_url( 'blocks/back-to-top/view.min.js', __DIR__ ),
array(),
'',
true
);
}
}
}
6 changes: 6 additions & 0 deletions packages/block-library/src/back-to-top/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Internal dependencies
*/
import { init } from './';

export default init();
40 changes: 40 additions & 0 deletions packages/block-library/src/back-to-top/view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* This script is needed to move the focus to the first focusable element on the page.
* It is only intended to be loaded on the front of classic themes that does not include wp_body_open().
*/
window.addEventListener( 'load', () => {
const backToTopBlocks = document.querySelectorAll(
'.wp-block-back-to-top'
);
function moveFocusToTop() {
const topAnchor = document.getElementById( '#wp-back-to-top' );
if ( topAnchor ) {
topAnchor.querySelector( 'a' ).focus();
return;
}
// This list is not exhaustive, but covers common elements that can recieve focus.
const focusable = [
'a[href]',
'audio',
'button:not([disabled])',
'[contenteditable]',
'details',
'embed',
'iframe',
'input:not([disabled]):not([type="hidden"])',
'object',
'[role="button"][tabindex="0"]',
'[role="link"][tabindex="0"]',
'select:not([disabled])',
'summary',
'textarea:not([disabled])',
'video',
'[tabindex]:not([tabindex="-1"])',
];
document.querySelector( focusable.join( ', ' ) ).focus();
}

backToTopBlocks.forEach( ( backToTop ) => {
backToTop.addEventListener( 'click', moveFocusToTop );
} );
} );
2 changes: 2 additions & 0 deletions packages/block-library/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import * as archives from './archives';
import * as avatar from './avatar';
import * as audio from './audio';
import * as backToTop from './back-to-top';
import * as button from './button';
import * as buttons from './buttons';
import * as calendar from './calendar';
Expand Down Expand Up @@ -142,6 +143,7 @@ const getAllBlocks = () => {
// Register all remaining core blocks.
archives,
audio,
backToTop,
button,
buttons,
calendar,
Expand Down
1 change: 1 addition & 0 deletions test/integration/fixtures/blocks/core__back-to-top.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- wp:back-to-top /-->
8 changes: 8 additions & 0 deletions test/integration/fixtures/blocks/core__back-to-top.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"name": "core/back-to-top",
"isValid": true,
"attributes": {},
"innerBlocks": []
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"blockName": "core/back-to-top",
"attrs": {},
"innerBlocks": [],
"innerHTML": "",
"innerContent": []
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- wp:back-to-top /-->
Loading