Date: Tue, 4 Feb 2020 14:37:42 +0000
Subject: [PATCH 058/170] Fix broken conditional exposed by test failures.
---
packages/block-editor/src/components/link-control/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js
index 62251060a614a5..f20f26766e73f2 100644
--- a/packages/block-editor/src/components/link-control/index.js
+++ b/packages/block-editor/src/components/link-control/index.js
@@ -452,7 +452,7 @@ function LinkControl( {
/>
) }
- { ! isEditingLink && ! isResolvingLink && (
+ { value && ! isEditingLink && ! isResolvingLink && (
Date: Tue, 4 Feb 2020 14:51:48 +0000
Subject: [PATCH 059/170] Fix to stop users without create pages permission
seeing the Create entity UI
---
.../block-library/src/navigation-link/edit.js | 76 ++++++++++++-------
1 file changed, 49 insertions(+), 27 deletions(-)
diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js
index cbd5186516fbf0..0508b092252cee 100644
--- a/packages/block-library/src/navigation-link/edit.js
+++ b/packages/block-library/src/navigation-link/edit.js
@@ -52,6 +52,7 @@ function NavigationLinkEdit( {
rgbTextColor,
rgbBackgroundColor,
saveEntityRecord,
+ userCanCreatePages = false,
} ) {
const { label, opensInNewTab, url, nofollow, description } = attributes;
const link = {
@@ -115,6 +116,43 @@ function NavigationLinkEdit( {
selection.addRange( range );
}
+ function handleCreateEntity( type, entityTitle ) {
+ return saveEntityRecord( 'postType', type, {
+ title: entityTitle,
+ status: 'publish',
+ } ).then( ( entity ) => {
+ // `entity` may not reject the Promise
+ // but may still be invalid. Here we
+ // tests for unexpected values and throw accordingly.
+ if ( null === entity || undefined === entity ) {
+ throw new TypeError(
+ 'API response returned invalid entity.',
+ entity
+ );
+ }
+
+ const requiredEntityProps = [ 'id', 'title', 'link' ];
+
+ const entityMissingProperty = requiredEntityProps.find(
+ ( entityProp ) => ! entity.hasOwnProperty( entityProp )
+ );
+
+ if ( Boolean( entityMissingProperty ) ) {
+ throw new TypeError(
+ `API response returned invalid entity. Missing required property "${ entityMissingProperty }".`,
+ entity
+ );
+ }
+
+ return {
+ id: entity.id,
+ type,
+ title: entity.title.raw, // TODO: use raw or rendered?
+ url: entity.link,
+ };
+ } );
+ }
+
return (
@@ -228,33 +266,10 @@ function NavigationLinkEdit( {
value={ link }
showInitialSuggestions={ true }
showCreateEntity={ true }
- createEntity={ ( type, entityTitle ) =>
- saveEntityRecord( 'postType', type, {
- title: entityTitle,
- status: 'publish',
- } ).then( ( entity ) => {
- // `entity` may not reject the Promise
- // but may still be invalid. Here we
- // tests for unexpected values and throw accordingly.
- if ( null === entity || undefined === entity ) {
- throw new TypeError( 'API response returned invalid entity.', entity );
- }
-
- const requiredEntityProps = ['id', 'title', 'link'];
-
- const entityMissingProperty = requiredEntityProps.find(entityProp => !entity.hasOwnProperty(entityProp));
-
- if (Boolean(entityMissingProperty)) {
- throw new TypeError(`API response returned invalid entity. Missing required property "${entityMissingProperty}".`, entity);
- }
-
- return {
- id: entity.id,
- type,
- title: entity.title.raw, // TODO: use raw or rendered?
- url: entity.link,
- };
- } )
+ createEntity={
+ userCanCreatePages
+ ? handleCreateEntity
+ : undefined
}
onChange={ ( {
title: newTitle = '',
@@ -350,12 +365,19 @@ export default compose( [
!! navigationBlockAttributes.showSubmenuIcon && hasDescendants;
const isParentOfSelectedBlock = hasSelectedInnerBlock( clientId, true );
+ const userCanCreatePages = select( 'core' ).canUser(
+ 'create',
+ 'pages'
+ );
+
return {
isParentOfSelectedBlock,
hasDescendants,
showSubmenuIcon,
textColor: navigationBlockAttributes.textColor,
backgroundColor: navigationBlockAttributes.backgroundColor,
+ navigationBlockAttributes,
+ userCanCreatePages,
rgbTextColor: getColorObjectByColorSlug(
colors,
navigationBlockAttributes.textColor,
From 8203176735ee42db1178300b9354b8970117fc57 Mon Sep 17 00:00:00 2001
From: Dave Smith
Date: Tue, 4 Feb 2020 15:52:21 +0000
Subject: [PATCH 060/170] Add test to verify Create UI not shown if valid
handler not provided to component
---
.../src/components/link-control/index.js | 2 -
.../src/components/link-control/test/index.js | 491 +++++++++++-------
2 files changed, 303 insertions(+), 190 deletions(-)
diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js
index f20f26766e73f2..60f5315792b4d6 100644
--- a/packages/block-editor/src/components/link-control/index.js
+++ b/packages/block-editor/src/components/link-control/index.js
@@ -101,7 +101,6 @@ function LinkControl( {
onChange = noop,
showInitialSuggestions,
forceIsEditingLink,
- showCreateEntity,
createEntity,
} ) {
const wrapperNode = useRef();
@@ -323,7 +322,6 @@ function LinkControl( {
suggestions[ 0 ].type.toLowerCase()
);
const shouldShowCreateEntity =
- showCreateEntity &&
createEntity &&
! isSingleDirectEntryResult &&
! isInitialSuggestions;
diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js
index 35375c53ef9cf6..4b821937869cd0 100644
--- a/packages/block-editor/src/components/link-control/test/index.js
+++ b/packages/block-editor/src/components/link-control/test/index.js
@@ -520,99 +520,129 @@ describe( 'Default search suggestions', () => {
describe( 'Creating Entities (eg: Posts, Pages)', () => {
const noResults = [];
beforeEach( () => {
-
-
// Force returning empty results for existing Pages. Doing this means that the only item
// shown should be "Create Page" suggestion because there will be no search suggestions
// and our input does not conform to a direct entry schema (eg: a URL).
- mockFetchSearchSuggestions.mockImplementation( () => Promise.resolve( noResults ) );
+ mockFetchSearchSuggestions.mockImplementation( () =>
+ Promise.resolve( noResults )
+ );
} );
it.each( [
[ 'HelloWorld', 'without spaces' ],
[ 'Hello World', 'with spaces' ],
- ] )( 'should allow creating a link for a valid Entity title "%s" (%s)', async ( entityNameText ) => {
+ ] )(
+ 'should allow creating a link for a valid Entity title "%s" (%s)',
+ async ( entityNameText ) => {
+ let resolver;
+ let resolvedEntity;
+ let currentLinkLabel;
+
+ const createEntity = ( type, title ) =>
+ new Promise( ( resolve ) => {
+ resolver = resolve;
+ resolvedEntity = {
+ type,
+ title,
+ id: 123,
+ url: '/?p=123',
+ };
+ } );
+ const LinkControlConsumer = () => {
+ const [ link, setLink ] = useState( null );
- let resolver;
- let resolvedEntity;
- let currentLinkLabel;
-
- const createEntity = (type, title) => new Promise((resolve) => {
- resolver = resolve;
- resolvedEntity = {
- type,
- title,
- id: 123,
- url: '/?p=123',
+ return (
+ {
+ setLink( suggestion );
+ } }
+ createEntity={ createEntity }
+ />
+ );
};
- });
- const LinkControlConsumer = () => {
- const [ link, setLink ] = useState( null );
-
- return ( {
- setLink( suggestion );
- } }
- createEntity={ createEntity }
- /> );
- };
-
- act( () => {
- render( , container );
- } );
+ act( () => {
+ render( , container );
+ } );
- // Search Input UI
- const searchInput = container.querySelector( 'input[aria-label="URL"]' );
+ // Search Input UI
+ const searchInput = container.querySelector(
+ 'input[aria-label="URL"]'
+ );
- // Simulate searching for a term
- act( () => {
- Simulate.change( searchInput, { target: { value: entityNameText } } );
- } );
+ // Simulate searching for a term
+ act( () => {
+ Simulate.change( searchInput, {
+ target: { value: entityNameText },
+ } );
+ } );
- await eventLoopTick();
+ await eventLoopTick();
- // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
- const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
+ // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
+ const searchResultElements = container.querySelectorAll(
+ '[role="listbox"] [role="option"]'
+ );
- const createButton = first( Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) ) );
+ const createButton = first(
+ Array.from( searchResultElements ).filter( ( result ) =>
+ result.innerHTML.includes( 'Create new' )
+ )
+ );
- expect( createButton ).not.toBeNull();
- expect( createButton.innerHTML ).toEqual( expect.stringContaining( entityNameText ) );
+ expect( createButton ).not.toBeNull();
+ expect( createButton.innerHTML ).toEqual(
+ expect.stringContaining( entityNameText )
+ );
- // No need to wait in this test because we control the Promise
- // resolution manually via the `resolver` reference
- act( () => {
- Simulate.click( createButton );
- } );
+ // No need to wait in this test because we control the Promise
+ // resolution manually via the `resolver` reference
+ act( () => {
+ Simulate.click( createButton );
+ } );
- await eventLoopTick();
+ await eventLoopTick();
- // Check for loading indicator
- const loadingIndicator = container.querySelector('.block-editor-link-control__loading');
- currentLinkLabel = container.querySelector('[aria-label="Currently selected"]');
+ // Check for loading indicator
+ const loadingIndicator = container.querySelector(
+ '.block-editor-link-control__loading'
+ );
+ currentLinkLabel = container.querySelector(
+ '[aria-label="Currently selected"]'
+ );
- expect(currentLinkLabel).toBeNull();
- expect(loadingIndicator.innerHTML).toEqual(expect.stringContaining('Loading'));
+ expect( currentLinkLabel ).toBeNull();
+ expect( loadingIndicator.innerHTML ).toEqual(
+ expect.stringContaining( 'Loading' )
+ );
- // Resolve the `createEntity` promise
- await act( async () => {
- resolver(resolvedEntity);
- });
+ // Resolve the `createEntity` promise
+ await act( async () => {
+ resolver( resolvedEntity );
+ } );
- await eventLoopTick();
+ await eventLoopTick();
- // Test the new entity was displayed.
- currentLinkLabel = container.querySelector( '[aria-label="Currently selected"]' );
- const currentLink = container.querySelector( `[aria-labelledby="${ currentLinkLabel.id }"]` );
+ // Test the new entity was displayed.
+ currentLinkLabel = container.querySelector(
+ '[aria-label="Currently selected"]'
+ );
+ const currentLink = container.querySelector(
+ `[aria-labelledby="${ currentLinkLabel.id }"]`
+ );
- const currentLinkHTML = currentLink.innerHTML;
+ const currentLinkHTML = currentLink.innerHTML;
- expect( currentLinkHTML ).toEqual( expect.stringContaining( entityNameText ) ); //title
- expect( currentLinkHTML ).toEqual( expect.stringContaining( '/?p=123' ) ); // slug
- } );
+ expect( currentLinkHTML ).toEqual(
+ expect.stringContaining( entityNameText )
+ ); //title
+ expect( currentLinkHTML ).toEqual(
+ expect.stringContaining( '/?p=123' )
+ ); // slug
+ }
+ );
it( 'should allow creation of entities via the keyboard', async () => {
const entityNameText = 'A new page to be created';
@@ -620,19 +650,23 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
const LinkControlConsumer = () => {
const [ link, setLink ] = useState( null );
- return ( {
- setLink( suggestion );
- } }
- createEntity={ ( type, title ) => Promise.resolve( {
- type,
- title,
- id: 123,
- url: '/?p=123',
- } ) }
- /> );
+ return (
+ {
+ setLink( suggestion );
+ } }
+ createEntity={ ( type, title ) =>
+ Promise.resolve( {
+ type,
+ title,
+ id: 123,
+ url: '/?p=123',
+ } )
+ }
+ />
+ );
};
act( () => {
@@ -640,19 +674,29 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
} );
// Search Input UI
- const searchInput = container.querySelector( 'input[aria-label="URL"]' );
+ const searchInput = container.querySelector(
+ 'input[aria-label="URL"]'
+ );
// Simulate searching for a term
act( () => {
- Simulate.change( searchInput, { target: { value: entityNameText } } );
+ Simulate.change( searchInput, {
+ target: { value: entityNameText },
+ } );
} );
await eventLoopTick();
// TODO: select these by aria relationship to autocomplete rather than arbitary selector.
- const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
- const form = container.querySelector('form');
- const createButton = first( Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) ) );
+ const searchResultElements = container.querySelectorAll(
+ '[role="listbox"] [role="option"]'
+ );
+ const form = container.querySelector( 'form' );
+ const createButton = first(
+ Array.from( searchResultElements ).filter( ( result ) =>
+ result.innerHTML.includes( 'Create new' )
+ )
+ );
// Step down into the search results, highlighting the first result item
act( () => {
@@ -663,140 +707,211 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
Simulate.keyDown( createButton, { keyCode: ENTER } );
} );
- await act(async () => {
- Simulate.submit(form);
- });
+ await act( async () => {
+ Simulate.submit( form );
+ } );
await eventLoopTick();
- const currentLinkLabel = container.querySelector( '[aria-label="Currently selected"]' );
+ const currentLinkLabel = container.querySelector(
+ '[aria-label="Currently selected"]'
+ );
- const currentLink = container.querySelector( `[aria-labelledby="${ currentLinkLabel.id }"]` );
+ const currentLink = container.querySelector(
+ `[aria-labelledby="${ currentLinkLabel.id }"]`
+ );
const currentLinkHTML = currentLink.innerHTML;
- expect( currentLinkHTML ).toEqual( expect.stringContaining( entityNameText ) ); //title
+ expect( currentLinkHTML ).toEqual(
+ expect.stringContaining( entityNameText )
+ ); //title
} );
- it( 'should not show not show an option to create an entity when input is empty', async () => {
- act( () => {
- render(
- , container
+ describe( 'No create option', () => {
+ it.each( [ [ undefined ], [ null ], [ false ] ] )(
+ 'should not show not show an option to create an entity when "createEntity" handler is %s',
+ async ( handler ) => {
+ act( () => {
+ render(
+ ,
+ container
+ );
+ } );
+ // Await the initial suggestions to be fetched
+ await eventLoopTick();
+
+ // Search Input UI
+ const searchInput = container.querySelector(
+ 'input[aria-label="URL"]'
+ );
+
+ // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
+ const searchResultElements = container.querySelectorAll(
+ '[role="listbox"] [role="option"]'
+ );
+ const createButton = first(
+ Array.from( searchResultElements ).filter( ( result ) =>
+ result.innerHTML.includes( 'Create new' )
+ )
+ );
+
+ // Verify input has no value
+ expect( searchInput.value ).toBe( '' );
+ expect( createButton ).toBeFalsy(); // shouldn't exist!
+ }
+ );
+
+ it( 'should not show not show an option to create an entity when input is empty', async () => {
+ act( () => {
+ render(
+ ,
+ container
+ );
+ } );
+ // Await the initial suggestions to be fetched
+ await eventLoopTick();
+
+ // Search Input UI
+ const searchInput = container.querySelector(
+ 'input[aria-label="URL"]'
);
- } );
- // Await the initial suggestions to be fetched
- await eventLoopTick();
- // Search Input UI
- const searchInput = container.querySelector( 'input[aria-label="URL"]' );
+ // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
+ const searchResultElements = container.querySelectorAll(
+ '[role="listbox"] [role="option"]'
+ );
+ const createButton = first(
+ Array.from( searchResultElements ).filter( ( result ) =>
+ result.innerHTML.includes( 'Create new' )
+ )
+ );
- // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
- const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
- const createButton = first( Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) ) );
+ // Verify input has no value
+ expect( searchInput.value ).toBe( '' );
+ expect( createButton ).toBeFalsy(); // shouldn't exist!
+ } );
- // Verify input has no value
- expect( searchInput.value ).toBe( '' );
- expect( createButton ).toBeFalsy(); // shouldn't exist!
+ // it.each( [
+ // 'https://wordpress.org',
+ // 'www.wordpress.org',
+ // 'mailto:example123456@wordpress.org',
+ // 'tel:example123456@wordpress.org',
+ // '#internal-anchor',
+ // ] )( 'should not show option to "Create Page" when text is a form of direct entry (eg: %s)', async ( inputText ) => {
+ // act( () => {
+ // render(
+ // , container
+ // );
+ // } );
+
+ // // Search Input UI
+ // const searchInput = container.querySelector( 'input[aria-label="URL"]' );
+
+ // // Simulate searching for a term
+ // act( () => {
+ // Simulate.change( searchInput, { target: { value: inputText } } );
+ // } );
+
+ // await eventLoopTick();
+
+ // // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
+ // const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
+
+ // const createButton = Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) );
+
+ // expect( createButton ).toBeNull();
+ // } );
} );
- // it.each( [
- // 'https://wordpress.org',
- // 'www.wordpress.org',
- // 'mailto:example123456@wordpress.org',
- // 'tel:example123456@wordpress.org',
- // '#internal-anchor',
- // ] )( 'should not show option to "Create Page" when text is a form of direct entry (eg: %s)', async ( inputText ) => {
- // act( () => {
- // render(
- // , container
- // );
- // } );
-
- // // Search Input UI
- // const searchInput = container.querySelector( 'input[aria-label="URL"]' );
-
- // // Simulate searching for a term
- // act( () => {
- // Simulate.change( searchInput, { target: { value: inputText } } );
- // } );
-
- // await eventLoopTick();
-
- // // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
- // const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
-
- // const createButton = Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) );
-
- // expect( createButton ).toBeNull();
- // } );
-
- it( 'should display human readable error notice and re-show create button and search input if page creation request fails', async () => {
- const searchText = 'This page to be created';
- let searchInput;
+ describe( 'Error handling', () => {
+ it( 'should display human readable error notice and re-show create button and search input if page creation request fails', async () => {
+ const searchText = 'This page to be created';
+ let searchInput;
- const throwsError = () => {
- throw new Error( 'API response returned invalid entity.' ); // this can be any error and msg
- };
+ const throwsError = () => {
+ throw new Error( 'API response returned invalid entity.' ); // this can be any error and msg
+ };
- const createEntity = () => Promise.reject( throwsError() );
+ const createEntity = () => Promise.reject( throwsError() );
- act( () => {
- render(
- , container
- );
- } );
+ act( () => {
+ render(
+ ,
+ container
+ );
+ } );
- // Search Input UI
- searchInput = container.querySelector( 'input[aria-label="URL"]' );
+ // Search Input UI
+ searchInput = container.querySelector( 'input[aria-label="URL"]' );
- // Simulate searching for a term
- act( () => {
- Simulate.change( searchInput, { target: { value: searchText } } );
- } );
+ // Simulate searching for a term
+ act( () => {
+ Simulate.change( searchInput, {
+ target: { value: searchText },
+ } );
+ } );
- await eventLoopTick();
+ await eventLoopTick();
- // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
- let searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
- let createButton = first( Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) ) );
+ // TODO: select these by aria relationship to autocomplete rather than arbitary selector.
+ let searchResultElements = container.querySelectorAll(
+ '[role="listbox"] [role="option"]'
+ );
+ let createButton = first(
+ Array.from( searchResultElements ).filter( ( result ) =>
+ result.innerHTML.includes( 'Create new' )
+ )
+ );
- await act( async () => {
- Simulate.click( createButton );
- } );
+ await act( async () => {
+ Simulate.click( createButton );
+ } );
- await eventLoopTick();
+ await eventLoopTick();
- searchInput = container.querySelector( 'input[aria-label="URL"]' );
+ searchInput = container.querySelector( 'input[aria-label="URL"]' );
- // This is a Notice component wrapped in an aria-live div with role of "alert".
- const errorNotice = container.querySelector( '[role="alert"]' );
+ // This is a Notice component wrapped in an aria-live div with role of "alert".
+ const errorNotice = container.querySelector( '[role="alert"]' );
- // Catch the error in the test to avoid test failures
- expect( throwsError ).toThrow( Error );
+ // Catch the error in the test to avoid test failures
+ expect( throwsError ).toThrow( Error );
- // Check human readable error notice is displayed
- expect( errorNotice ).not.toBeFalsy();
- expect( errorNotice.innerHTML ).toEqual( expect.stringContaining( 'An unknown error occurred during Page creation. Please try again.' ) );
+ // Check human readable error notice is displayed
+ expect( errorNotice ).not.toBeFalsy();
+ expect( errorNotice.innerHTML ).toEqual(
+ expect.stringContaining(
+ 'An unknown error occurred during Page creation. Please try again.'
+ )
+ );
- // Verify input is repopulated with original search text
- expect( searchInput ).not.toBeFalsy();
- expect( searchInput.value ).toBe( searchText );
+ // Verify input is repopulated with original search text
+ expect( searchInput ).not.toBeFalsy();
+ expect( searchInput.value ).toBe( searchText );
- // Verify search results are re-shown and create button is available.
- searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
- createButton = first( Array.from( searchResultElements ).filter( ( result ) => result.innerHTML.includes( 'Create new' ) ) );
+ // Verify search results are re-shown and create button is available.
+ searchResultElements = container.querySelectorAll(
+ '[role="listbox"] [role="option"]'
+ );
+ createButton = first(
+ Array.from( searchResultElements ).filter( ( result ) =>
+ result.innerHTML.includes( 'Create new' )
+ )
+ );
- expect( createButton ).not.toBeFalsy(); // shouldn't exist!
+ expect( createButton ).not.toBeFalsy(); // shouldn't exist!
+ } );
} );
} );
From fe7a96f31ccaf4526f3a0b079a7f67016bfc7b20 Mon Sep 17 00:00:00 2001
From: Jerry Jones
Date: Tue, 4 Feb 2020 14:49:40 -0600
Subject: [PATCH 061/170] Renamed 'Loading...' to 'Creating Page' to match
mockup
---
packages/block-editor/src/components/link-control/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js
index 60f5315792b4d6..b88d7556d798e1 100644
--- a/packages/block-editor/src/components/link-control/index.js
+++ b/packages/block-editor/src/components/link-control/index.js
@@ -420,7 +420,7 @@ function LinkControl( {
>
{ isResolvingLink && (
- { __( 'Loading' ) }...
+ { __( 'Creating Page' ) }
) }
From 3263bb59fac22ea8f93e93e4d745ee1310816c1e Mon Sep 17 00:00:00 2001
From: Jerry Jones
Date: Tue, 4 Feb 2020 15:06:55 -0600
Subject: [PATCH 062/170] Adds the component to the Creating Page
loading state
---
.../block-editor/src/components/link-control/index.js | 9 +++++++--
.../block-editor/src/components/link-control/style.scss | 6 ++++++
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js
index b88d7556d798e1..e8ea1c0209129b 100644
--- a/packages/block-editor/src/components/link-control/index.js
+++ b/packages/block-editor/src/components/link-control/index.js
@@ -7,7 +7,12 @@ import { noop, startsWith, uniqueId } from 'lodash';
/**
* WordPress dependencies
*/
-import { Button, ExternalLink, VisuallyHidden } from '@wordpress/components';
+import {
+ Button,
+ ExternalLink,
+ Spinner,
+ VisuallyHidden,
+} from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import {
useRef,
@@ -420,7 +425,7 @@ function LinkControl( {
>
{ isResolvingLink && (
- { __( 'Creating Page' ) }
+ { __( 'Creating Page' ) }
) }
diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss
index f907180bf31307..327f84d0bb6e15 100644
--- a/packages/block-editor/src/components/link-control/style.scss
+++ b/packages/block-editor/src/components/link-control/style.scss
@@ -195,6 +195,12 @@ $block-editor-link-control-number-of-actions: 1;
.block-editor-link-control__loading {
margin: $grid-size-large; // when only loading control is shown it requires it's own spacing.
+ display: flex;
+ align-items: center;
+
+ .components-spinner {
+ margin-top: 0;
+ }
}
.block-editor-link-control__search-create {
From b1925205ba10647a176bcd146fbfc443bb520514 Mon Sep 17 00:00:00 2001
From: Jerry Jones
Date: Tue, 4 Feb 2020 15:44:27 -0600
Subject: [PATCH 063/170] Reduced padding on bottom of LinkControl list results
and moved error message up to match design specs more closely.
---
packages/block-editor/src/components/link-control/style.scss | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss
index 327f84d0bb6e15..8928b67dd5fe88 100644
--- a/packages/block-editor/src/components/link-control/style.scss
+++ b/packages/block-editor/src/components/link-control/style.scss
@@ -38,7 +38,7 @@ $block-editor-link-control-number-of-actions: 1;
}
.block-editor-link-control__search-error {
- margin: 0 20px 20px 20px;
+ margin: -$grid-size-large/2 $grid-size-large $grid-size-large;
}
.block-editor-link-control__search-actions {
@@ -97,7 +97,7 @@ $block-editor-link-control-number-of-actions: 1;
.block-editor-link-control__search-results {
margin: 0;
- padding: $grid-size-large/2 $grid-size-large $grid-size-large;
+ padding: $grid-size-large/2 $grid-size-large $grid-size-large/2;
max-height: 200px;
overflow-y: auto; // allow results list to scroll
From ee4ce2c072816f3404f71c5d513badbd0ae558a0 Mon Sep 17 00:00:00 2001
From: Konstantin Obenland
Date: Tue, 4 Feb 2020 13:30:18 -0800
Subject: [PATCH 064/170] Only add separator when it needs separating
We only need a separator when there are other suggestions the Create button needs separation from.
---
packages/block-editor/src/components/link-control/style.scss | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss
index 8928b67dd5fe88..6f9845dc2a4203 100644
--- a/packages/block-editor/src/components/link-control/style.scss
+++ b/packages/block-editor/src/components/link-control/style.scss
@@ -203,7 +203,8 @@ $block-editor-link-control-number-of-actions: 1;
}
}
-.block-editor-link-control__search-create {
+// Separate Create button when following other suggestions.
+.components-button + .block-editor-link-control__search-create {
margin-top: 20px;
overflow: visible;
From 996a99264f4d85473f29a64b172d07d015b3b0a4 Mon Sep 17 00:00:00 2001
From: Jerry Jones
Date: Tue, 4 Feb 2020 16:05:10 -0600
Subject: [PATCH 065/170] Committed formatted js
---
.../link-control/search-create-button.js | 27 ++++++++++++-------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/packages/block-editor/src/components/link-control/search-create-button.js b/packages/block-editor/src/components/link-control/search-create-button.js
index 12e047de21bcb7..8ca44502e65ce3 100644
--- a/packages/block-editor/src/components/link-control/search-create-button.js
+++ b/packages/block-editor/src/components/link-control/search-create-button.js
@@ -7,21 +7,29 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
-import {
- Button,
- Icon,
-} from '@wordpress/components';
+import { Button, Icon } from '@wordpress/components';
-export const LinkControlSearchCreate = ( { searchTerm = '', onClick, itemProps, isSelected } ) => {
+export const LinkControlSearchCreate = ( {
+ searchTerm = '',
+ onClick,
+ itemProps,
+ isSelected,
+} ) => {
return (