Skip to content

Commit

Permalink
Navigation Link Block: Add State for Missing URL (#28861)
Browse files Browse the repository at this point in the history
When the URL is missing from a Navigation Link Block:

- Adds a placeholder
- Forces the URL popover open when the block is selected
- Prevents editing the text until a URL is added

Bugfix:
 - Cancels any outstanding requests in URLInput when the component is unmounted to avoid calling setState on an unmounted component

Co-authored-by: Kerry Liu <[email protected]>
Co-authored-by: jasmussen <[email protected]>
  • Loading branch information
3 people authored Feb 26, 2021
1 parent acae1d4 commit 59d6cbf
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 28 deletions.
6 changes: 5 additions & 1 deletion packages/block-editor/src/components/link-control/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,17 @@ $block-editor-link-control-number-of-actions: 1;
}

.block-editor-link-control__settings {
border-top: 1px solid $gray-300;
border-top: $border-width solid $gray-300;
margin: 0;
padding: $grid-unit-20 $grid-unit-30;

:last-child {
margin-bottom: 0;
}

.is-alternate & {
border-top: $border-width solid $gray-900;
}
}

.block-editor-link-control__setting {
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/components/url-input/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class URLInput extends Component {
}

componentWillUnmount() {
this.suggestionsRequest?.cancel?.();
delete this.suggestionsRequest;
}

Expand Down
108 changes: 81 additions & 27 deletions packages/block-library/src/navigation-link/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ export default function NavigationLinkEdit( {
},
} );

if ( ! url ) {
blockProps.onClick = () => setIsLinkOpen( true );
}

const innerBlocksProps = useInnerBlocksProps(
{
className: classnames( 'wp-block-navigation__container', {
Expand All @@ -332,6 +336,33 @@ export default function NavigationLinkEdit( {
}
);

const classes = classnames( 'wp-block-navigation-link__content', {
'wp-block-navigation-link__placeholder': ! url,
} );

let missingText = '';
switch ( type ) {
case 'post':
/* translators: label for missing post in navigation link block */
missingText = __( 'Select a post' );
break;
case 'page':
/* translators: label for missing page in navigation link block */
missingText = __( 'Select a page' );
break;
case 'category':
/* translators: label for missing category in navigation link block */
missingText = __( 'Select a category' );
break;
case 'tag':
/* translators: label for missing tag in navigation link block */
missingText = __( 'Select a tag' );
break;
default:
/* translators: label for missing values in navigation link block */
missingText = __( 'Add a link' );
}

return (
<Fragment>
<BlockControls>
Expand Down Expand Up @@ -389,38 +420,61 @@ export default function NavigationLinkEdit( {
</PanelBody>
</InspectorControls>
<li { ...blockProps }>
<div className="wp-block-navigation-link__content">
<RichText
ref={ ref }
identifier="label"
className="wp-block-navigation-link__label"
value={ label }
onChange={ ( labelValue ) =>
setAttributes( { label: labelValue } )
}
onMerge={ mergeBlocks }
onReplace={ onReplace }
__unstableOnSplitAtEnd={ () =>
insertBlocksAfter(
createBlock( 'core/navigation-link' )
)
}
aria-label={ __( 'Navigation link text' ) }
placeholder={ itemLabelPlaceholder }
keepPlaceholderOnFocus
withoutInteractiveFormatting
allowedFormats={ [
'core/bold',
'core/italic',
'core/image',
'core/strikethrough',
] }
/>
<div className={ classes }>
{ ! url ? (
<div className="wp-block-navigation-link__placeholder-text">
<KeyboardShortcuts
shortcuts={ {
enter: () =>
isSelected && setIsLinkOpen( true ),
} }
/>
{ missingText }
</div>
) : (
<RichText
ref={ ref }
identifier="label"
className="wp-block-navigation-link__label"
value={ label }
onChange={ ( labelValue ) =>
setAttributes( { label: labelValue } )
}
onMerge={ mergeBlocks }
onReplace={ onReplace }
__unstableOnSplitAtEnd={ () =>
insertBlocksAfter(
createBlock( 'core/navigation-link' )
)
}
aria-label={ __( 'Navigation link text' ) }
placeholder={ itemLabelPlaceholder }
keepPlaceholderOnFocus
withoutInteractiveFormatting
allowedFormats={ [
'core/bold',
'core/italic',
'core/image',
'core/strikethrough',
] }
onClick={ () => {
if ( ! url ) {
setIsLinkOpen( true );
}
} }
/>
) }
{ isLinkOpen && (
<Popover
position="bottom center"
onClose={ () => setIsLinkOpen( false ) }
>
<KeyboardShortcuts
bindGlobal
shortcuts={ {
escape: () => setIsLinkOpen( false ),
} }
/>
<LinkControl
className="wp-block-navigation-link__inline-link-input"
value={ link }
Expand Down
44 changes: 44 additions & 0 deletions packages/block-library/src/navigation-link/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,47 @@
display: none;
}
}

// Menu item setup state, is shown when a menu item has no URL configured.
.wp-block-navigation-link__placeholder {
position: relative;
cursor: pointer;

// Provide a little margin to show each placeholder as a separate unit.
margin: 2px;

.wp-block-navigation-link__placeholder-text {
font-family: $default-font;
font-size: $default-font-size;
}

&::before {
content: "";
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-radius: $radius-block-ui;
opacity: 0.1;

.is-dark-theme & {
opacity: 0.2;
}

.is-editing & {
background: currentColor;
}
}
}

// We had to add extra classes to override the color from
// .editor-styles-wrapper .wp-block-navigation:not(.has-text-color) .wp-block-navigation-link__content
.wp-block-navigation
.wp-block-navigation-link:not(.is-editing)
.wp-block-navigation-link__content.wp-block-navigation-link__placeholder {
box-shadow: inset 0 0 0 $border-width $gray-700;
border-radius: $radius-block-ui;
color: var(--wp-admin-theme-color);
}

0 comments on commit 59d6cbf

Please sign in to comment.