Skip to content

Commit

Permalink
New Block: Link Wrapper to add a link to a group of blocks.
Browse files Browse the repository at this point in the history
  • Loading branch information
ryelle committed May 9, 2023
1 parent 794d704 commit d4b9659
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 0 deletions.
24 changes: 24 additions & 0 deletions mu-plugins/blocks/link-wrapper/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Block Name: Link Wrapper
* Description: Link a set of blocks to a given page.
*
* @package wporg
*/

namespace WordPressdotorg\MU_Plugins\Link_Wrapper_Block;

use function WordPressdotorg\MU_Plugins\Helpers\register_assets_from_metadata;

add_action( 'init', __NAMESPACE__ . '\init' );

/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function init() {
register_block_type( __DIR__ . '/build' );
}
34 changes: 34 additions & 0 deletions mu-plugins/blocks/link-wrapper/postcss/style.pcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.wp-block-wporg-link-wrapper {
position: relative;
display: block;
text-decoration: none !important;
color: var(--wp--preset--color--charcoal-1);
overflow: hidden;

&:focus-visible {
outline: none;
}

&:hover {
text-decoration: underline !important;
}

/* Put the outline on `after` to ensure it's visible over a Cover block. */
&:focus-visible::after {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 10;
content: "";
outline: 1.5px solid var(--wp--preset--color--blueberry-1);
outline-offset: -1.5px;
box-shadow: inset 0 0 0 3px var(--wp--preset--color--white);
border-radius: inherit;
}

& .wporg-link-wrapper__notice {
margin: 1em 0 0;
}
}
53 changes: 53 additions & 0 deletions mu-plugins/blocks/link-wrapper/src/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "wporg/link-wrapper",
"title": "Link Wrapper",
"icon": "admin-links",
"category": "layout",
"description": "Link a set of blocks to a given page.",
"textdomain": "wporg",
"attributes": {
"url": {
"type": "string",
"source": "attribute",
"selector": "a",
"attribute": "href"
}
},
"supports": {
"align": true,
"color": {
"text": true,
"background": true,
"link": false
},
"spacing": {
"margin": true,
"padding": true,
"__experimentalDefaultControls": {
"margin": true,
"padding": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"__experimentalBorder": {
"color": true,
"radius": true,
"style": true,
"width": true,
"__experimentalDefaultControls": {
"color": true,
"radius": true,
"style": true,
"width": true
}
},
"__experimentalLayout": true
},
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
66 changes: 66 additions & 0 deletions mu-plugins/blocks/link-wrapper/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { useRef } from '@wordpress/element';
import { InnerBlocks, InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { Notice, PanelBody, TextControl } from '@wordpress/components';

/**
* Internal dependencies
*/
import metadata from './block.json';

function Edit( { attributes, setAttributes } ) {
const wrapperRef = useRef();

// Check for nested links or buttons. This doesn't catch every case, since
// some blocks have settings to output links on the frontend (images), but
// it provides some guardrails to validate the content.
const links = wrapperRef.current?.querySelectorAll( 'a,[data-type="core/button"]' ) || [];

return (
<>
<InspectorControls key="setting">
<PanelBody title={ __( 'Link destination', 'wporg' ) }>
<TextControl
label={ __( 'Link destination', 'wporg' ) }
hideLabelFromVision
value={ attributes.url }
onChange={ ( val ) => setAttributes( { url: val } ) }
type="url"
/>
</PanelBody>
</InspectorControls>
<div { ...useBlockProps( { ref: wrapperRef } ) }>
<InnerBlocks />
{ !! links.length && (
<Notice
className="wporg-link-wrapper__notice"
spokenMessage={ null }
status="warning"
isDismissible={ false }
>
{ __(
'This block should not contain links or buttons. Remove the link, or use a different container.',
'wporg'
) }
</Notice>
) }
</div>
</>
);
}

registerBlockType( metadata.name, {
edit: Edit,
save: ( { attributes } ) => {
const blockProps = useBlockProps.save();
return (
<a { ...blockProps } href={ attributes.url }>
<InnerBlocks.Content />
</a>
);
},
} );
1 change: 1 addition & 0 deletions mu-plugins/loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
require_once __DIR__ . '/blocks/horizontal-slider/horizontal-slider.php';
require_once __DIR__ . '/blocks/language-suggest/language-suggest.php';
require_once __DIR__ . '/blocks/latest-news/latest-news.php';
require_once __DIR__ . '/blocks/link-wrapper/index.php';
require_once __DIR__ . '/blocks/notice/index.php';
require_once __DIR__ . '/blocks/sidebar-container/index.php';
require_once __DIR__ . '/blocks/screenshot-preview/block.php';
Expand Down

0 comments on commit d4b9659

Please sign in to comment.