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

Update frame resizing #49910

Merged
merged 35 commits into from
May 19, 2023
Merged
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
8e9c1af
frame resizer centered
SaxonF Apr 19, 2023
0441dba
Use a lerp function to modify the height of the frame.
mtias Apr 24, 2023
43019aa
Make the frame full screen when the user resizes it to the left.
mtias Apr 24, 2023
63e5509
Ensure the frame grows only to the left when going above its size.
mtias Apr 24, 2023
77d55c4
Disable user selection while resizing the frame.
mtias Apr 24, 2023
b08b57a
Make it easier to grab the handle.
mtias Apr 25, 2023
17becce
Switch to setTimeout and set a fixed resizeRatio.
mtias Apr 25, 2023
59bfa2f
Modify oversized calculation to reduce resizing bug.
mtias Apr 25, 2023
d8dd107
Avoid timer
mirka May 5, 2023
6322c3c
Temp working
mirka May 8, 2023
1934811
Clean up CSS
mirka May 8, 2023
dbb51f9
More cleanup
mirka May 8, 2023
05c49fc
Refactor lerpy parts
mirka May 8, 2023
dc89a28
More cleanup
mirka May 8, 2023
0d19489
Rename `isFull` to `isFullWidth`
mirka May 8, 2023
602e612
Improve maintainability
mirka May 8, 2023
bdc1732
More cleanup
mirka May 8, 2023
34ccb00
Match component classnames
mirka May 8, 2023
0a2cb41
Invert control for flex changes
mirka May 9, 2023
b69ee87
Calculate fluid resize ratio
mirka May 10, 2023
3bb9c10
Prevent React re-render loop warning
mirka May 10, 2023
3ef1855
Always show handle when resizing
mirka May 10, 2023
a742569
Maintain resizing cursor when resizing
mirka May 10, 2023
48658ca
Improve code comments
mirka May 10, 2023
cd5bcc4
Exclude `ListPage` from ResizableFrame
mirka May 10, 2023
09bc6fd
Use CSS var for accent color
mirka May 10, 2023
d518f0e
Handle spinner gracefully
mirka May 10, 2023
ee461b9
Lift loading state so resizing can be disabled
mirka May 10, 2023
b85a344
Change max width for less jankiness
mirka May 10, 2023
334b643
Remove outdated padding animation
mirka May 10, 2023
44828f7
Clean up magic numbers
ciampo May 18, 2023
db6330c
Update saveSiteEditorEntities() locators
WunderBart May 19, 2023
929e903
Update StyleBook.open() locators
WunderBart May 19, 2023
5d53981
Quickfix: Wait until load spinner is gone
mirka May 19, 2023
a2bf020
Revert to class-based save detection
mirka May 19, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@ export async function visitSiteEditor(
.locator( 'body > *' )
.first()
.waitFor();

// TODO: Ideally the content underneath the spinner should be marked inert until it's ready.
await this.page
.locator( '.edit-site-canvas-spinner' )
.waitFor( { state: 'hidden' } );
}
28 changes: 19 additions & 9 deletions packages/e2e-test-utils-playwright/src/editor/site-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,25 @@ import type { Editor } from './index';
* @param this
*/
export async function saveSiteEditorEntities( this: Editor ) {
await this.page.click(
'role=region[name="Editor top bar"i] >> role=button[name="Save"i]'
);
const editorTopBar = this.page.getByRole( 'region', {
name: 'Editor top bar',
} );
const savePanel = this.page.getByRole( 'region', { name: 'Save panel' } );

// First Save button in the top bar.
await editorTopBar
.getByRole( 'button', { name: 'Save', exact: true } )
.click();

// Second Save button in the entities panel.
await this.page.click(
'role=region[name="Save panel"i] >> role=button[name="Save"i]'
);
await savePanel
.getByRole( 'button', { name: 'Save', exact: true } )
.click();

// A role selector cannot be used here because it needs to check that the `is-busy` class is not present.
await this.page.waitForSelector( '[aria-label="Saved"].is-busy', {
state: 'hidden',
} );
await this.page
.locator( '[aria-label="Editor top bar"] [aria-label="Saved"].is-busy' )
.waitFor( {
state: 'hidden',
} );
}
56 changes: 15 additions & 41 deletions packages/edit-site/src/components/editor/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { useEffect, useMemo, useState } from '@wordpress/element';
import { useMemo } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { Notice } from '@wordpress/components';
import { EntityProvider, store as coreStore } from '@wordpress/core-data';
import { EntityProvider } from '@wordpress/core-data';
import { store as preferencesStore } from '@wordpress/preferences';
import {
BlockContextProvider,
Expand Down Expand Up @@ -50,42 +55,7 @@ const interfaceLabels = {
footer: __( 'Editor footer' ),
};

function useIsSiteEditorLoading() {
ciampo marked this conversation as resolved.
Show resolved Hide resolved
const { isLoaded: hasLoadedPost } = useEditedEntityRecord();
const [ loaded, setLoaded ] = useState( false );
const inLoadingPause = useSelect(
( select ) => {
const hasResolvingSelectors =
select( coreStore ).hasResolvingSelectors();
return ! loaded && ! hasResolvingSelectors;
},
[ loaded ]
);

useEffect( () => {
if ( inLoadingPause ) {
/*
* We're using an arbitrary 1s timeout here to catch brief moments
* without any resolving selectors that would result in displaying
* brief flickers of loading state and loaded state.
*
* It's worth experimenting with different values, since this also
* adds 1s of artificial delay after loading has finished.
*/
const timeout = setTimeout( () => {
setLoaded( true );
}, 1000 );

return () => {
clearTimeout( timeout );
};
}
}, [ inLoadingPause ] );

return ! loaded || ! hasLoadedPost;
}

export default function Editor() {
export default function Editor( { isLoading } ) {
const {
record: editedPost,
getTitle,
Expand Down Expand Up @@ -188,8 +158,6 @@ export default function Editor() {
// action in <URlQueryController> from double-announcing.
useTitle( hasLoadedPost && title );

const isLoading = useIsSiteEditorLoading();

return (
<>
{ isLoading ? <CanvasSpinner /> : null }
Expand All @@ -205,7 +173,13 @@ export default function Editor() {
{ isEditMode && <StartTemplateOptions /> }
<InterfaceSkeleton
enableRegionNavigation={ false }
className={ showIconLabels && 'show-icon-labels' }
className={ classnames(
'edit-site-editor__interface-skeleton',
{
'show-icon-labels': showIconLabels,
'is-loading': isLoading,
}
) }
notices={
( isEditMode ||
window?.__experimentalEnableThemePreviews ) && (
Expand Down
10 changes: 10 additions & 0 deletions packages/edit-site/src/components/editor/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
.edit-site-editor__interface-skeleton {
opacity: 1;
transition: opacity 0.1s ease-out;
@include reduce-motion("transition");

&.is-loading {
opacity: 0;
}
}

.edit-site-editor__toggle-save-panel {
box-sizing: border-box;
width: $sidebar-width;
Expand Down
46 changes: 46 additions & 0 deletions packages/edit-site/src/components/layout/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* WordPress dependencies
*/
import { useEffect, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
*/
import useEditedEntityRecord from '../use-edited-entity-record';

export function useIsSiteEditorLoading() {
const { isLoaded: hasLoadedPost } = useEditedEntityRecord();
const [ loaded, setLoaded ] = useState( false );
const inLoadingPause = useSelect(
( select ) => {
const hasResolvingSelectors =
select( coreStore ).hasResolvingSelectors();
return ! loaded && ! hasResolvingSelectors;
},
[ loaded ]
);

useEffect( () => {
if ( inLoadingPause ) {
/*
* We're using an arbitrary 1s timeout here to catch brief moments
* without any resolving selectors that would result in displaying
* brief flickers of loading state and loaded state.
*
* It's worth experimenting with different values, since this also
* adds 1s of artificial delay after loading has finished.
*/
const timeout = setTimeout( () => {
setLoaded( true );
}, 1000 );

return () => {
clearTimeout( timeout );
};
}
}, [ inLoadingPause ] );

return ! loaded || ! hasLoadedPost;
}
Loading