Skip to content

Commit c689d9f

Browse files
SaxonFmtiasmirkaciampoWunderBart
authored
Update frame resizing (#49910)
* frame resizer centered * Use a lerp function to modify the height of the frame. It should gradually reduce from original aspect ratio until reaching a 9 / 19.5 view. * Make the frame full screen when the user resizes it to the left. Reset the initial aspect ratio if the frame is resized slightly, and trigger full screen if the frame is resized far enough over the sidebar. * Ensure the frame grows only to the left when going above its size. * Disable user selection while resizing the frame. * Make it easier to grab the handle. * Switch to setTimeout and set a fixed resizeRatio. * Modify oversized calculation to reduce resizing bug. * Avoid timer * Temp working * Clean up CSS * More cleanup * Refactor lerpy parts * More cleanup * Rename `isFull` to `isFullWidth` * Improve maintainability * More cleanup * Match component classnames * Invert control for flex changes * Calculate fluid resize ratio * Prevent React re-render loop warning * Always show handle when resizing * Maintain resizing cursor when resizing * Improve code comments * Exclude `ListPage` from ResizableFrame * Use CSS var for accent color * Handle spinner gracefully * Lift loading state so resizing can be disabled * Change max width for less jankiness * Remove outdated padding animation * Clean up magic numbers * Update saveSiteEditorEntities() locators * Update StyleBook.open() locators * Quickfix: Wait until load spinner is gone * Revert to class-based save detection The `.getByRole()` way resolves a bit too early. --------- Co-authored-by: Matías Ventura <[email protected]> Co-authored-by: Lena Morita <[email protected]> Co-authored-by: Marco Ciampini <[email protected]> Co-authored-by: Bart Kalisz <[email protected]>
1 parent 064f731 commit c689d9f

File tree

11 files changed

+461
-171
lines changed

11 files changed

+461
-171
lines changed

packages/e2e-test-utils-playwright/src/admin/visit-site-editor.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,9 @@ export async function visitSiteEditor(
5454
.locator( 'body > *' )
5555
.first()
5656
.waitFor();
57+
58+
// TODO: Ideally the content underneath the spinner should be marked inert until it's ready.
59+
await this.page
60+
.locator( '.edit-site-canvas-spinner' )
61+
.waitFor( { state: 'hidden' } );
5762
}

packages/e2e-test-utils-playwright/src/editor/site-editor.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,25 @@ import type { Editor } from './index';
99
* @param this
1010
*/
1111
export async function saveSiteEditorEntities( this: Editor ) {
12-
await this.page.click(
13-
'role=region[name="Editor top bar"i] >> role=button[name="Save"i]'
14-
);
12+
const editorTopBar = this.page.getByRole( 'region', {
13+
name: 'Editor top bar',
14+
} );
15+
const savePanel = this.page.getByRole( 'region', { name: 'Save panel' } );
16+
17+
// First Save button in the top bar.
18+
await editorTopBar
19+
.getByRole( 'button', { name: 'Save', exact: true } )
20+
.click();
21+
1522
// Second Save button in the entities panel.
16-
await this.page.click(
17-
'role=region[name="Save panel"i] >> role=button[name="Save"i]'
18-
);
23+
await savePanel
24+
.getByRole( 'button', { name: 'Save', exact: true } )
25+
.click();
26+
1927
// A role selector cannot be used here because it needs to check that the `is-busy` class is not present.
20-
await this.page.waitForSelector( '[aria-label="Saved"].is-busy', {
21-
state: 'hidden',
22-
} );
28+
await this.page
29+
.locator( '[aria-label="Editor top bar"] [aria-label="Saved"].is-busy' )
30+
.waitFor( {
31+
state: 'hidden',
32+
} );
2333
}

packages/edit-site/src/components/editor/index.js

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import classnames from 'classnames';
5+
16
/**
27
* WordPress dependencies
38
*/
4-
import { useEffect, useMemo, useState } from '@wordpress/element';
9+
import { useMemo } from '@wordpress/element';
510
import { useSelect, useDispatch } from '@wordpress/data';
611
import { Notice } from '@wordpress/components';
7-
import { EntityProvider, store as coreStore } from '@wordpress/core-data';
12+
import { EntityProvider } from '@wordpress/core-data';
813
import { store as preferencesStore } from '@wordpress/preferences';
914
import {
1015
BlockContextProvider,
@@ -50,42 +55,7 @@ const interfaceLabels = {
5055
footer: __( 'Editor footer' ),
5156
};
5257

53-
function useIsSiteEditorLoading() {
54-
const { isLoaded: hasLoadedPost } = useEditedEntityRecord();
55-
const [ loaded, setLoaded ] = useState( false );
56-
const inLoadingPause = useSelect(
57-
( select ) => {
58-
const hasResolvingSelectors =
59-
select( coreStore ).hasResolvingSelectors();
60-
return ! loaded && ! hasResolvingSelectors;
61-
},
62-
[ loaded ]
63-
);
64-
65-
useEffect( () => {
66-
if ( inLoadingPause ) {
67-
/*
68-
* We're using an arbitrary 1s timeout here to catch brief moments
69-
* without any resolving selectors that would result in displaying
70-
* brief flickers of loading state and loaded state.
71-
*
72-
* It's worth experimenting with different values, since this also
73-
* adds 1s of artificial delay after loading has finished.
74-
*/
75-
const timeout = setTimeout( () => {
76-
setLoaded( true );
77-
}, 1000 );
78-
79-
return () => {
80-
clearTimeout( timeout );
81-
};
82-
}
83-
}, [ inLoadingPause ] );
84-
85-
return ! loaded || ! hasLoadedPost;
86-
}
87-
88-
export default function Editor() {
58+
export default function Editor( { isLoading } ) {
8959
const {
9060
record: editedPost,
9161
getTitle,
@@ -188,8 +158,6 @@ export default function Editor() {
188158
// action in <URlQueryController> from double-announcing.
189159
useTitle( hasLoadedPost && title );
190160

191-
const isLoading = useIsSiteEditorLoading();
192-
193161
return (
194162
<>
195163
{ isLoading ? <CanvasSpinner /> : null }
@@ -205,7 +173,13 @@ export default function Editor() {
205173
{ isEditMode && <StartTemplateOptions /> }
206174
<InterfaceSkeleton
207175
enableRegionNavigation={ false }
208-
className={ showIconLabels && 'show-icon-labels' }
176+
className={ classnames(
177+
'edit-site-editor__interface-skeleton',
178+
{
179+
'show-icon-labels': showIconLabels,
180+
'is-loading': isLoading,
181+
}
182+
) }
209183
notices={
210184
( isEditMode ||
211185
window?.__experimentalEnableThemePreviews ) && (

packages/edit-site/src/components/editor/style.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
.edit-site-editor__interface-skeleton {
2+
opacity: 1;
3+
transition: opacity 0.1s ease-out;
4+
@include reduce-motion("transition");
5+
6+
&.is-loading {
7+
opacity: 0;
8+
}
9+
}
10+
111
.edit-site-editor__toggle-save-panel {
212
box-sizing: border-box;
313
width: $sidebar-width;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { useEffect, useState } from '@wordpress/element';
5+
import { useSelect } from '@wordpress/data';
6+
import { store as coreStore } from '@wordpress/core-data';
7+
8+
/**
9+
* Internal dependencies
10+
*/
11+
import useEditedEntityRecord from '../use-edited-entity-record';
12+
13+
export function useIsSiteEditorLoading() {
14+
const { isLoaded: hasLoadedPost } = useEditedEntityRecord();
15+
const [ loaded, setLoaded ] = useState( false );
16+
const inLoadingPause = useSelect(
17+
( select ) => {
18+
const hasResolvingSelectors =
19+
select( coreStore ).hasResolvingSelectors();
20+
return ! loaded && ! hasResolvingSelectors;
21+
},
22+
[ loaded ]
23+
);
24+
25+
useEffect( () => {
26+
if ( inLoadingPause ) {
27+
/*
28+
* We're using an arbitrary 1s timeout here to catch brief moments
29+
* without any resolving selectors that would result in displaying
30+
* brief flickers of loading state and loaded state.
31+
*
32+
* It's worth experimenting with different values, since this also
33+
* adds 1s of artificial delay after loading has finished.
34+
*/
35+
const timeout = setTimeout( () => {
36+
setLoaded( true );
37+
}, 1000 );
38+
39+
return () => {
40+
clearTimeout( timeout );
41+
};
42+
}
43+
}, [ inLoadingPause ] );
44+
45+
return ! loaded || ! hasLoadedPost;
46+
}

0 commit comments

Comments
 (0)