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

Distraction Free: Unify the header animation #62167

Merged
merged 3 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 9 additions & 44 deletions packages/edit-site/src/components/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,8 @@ import clsx from 'clsx';
* WordPress dependencies
*/
import { useDispatch, useSelect } from '@wordpress/data';
import {
Notice,
__unstableAnimatePresence as AnimatePresence,
__unstableMotion as motion,
} from '@wordpress/components';
import {
useInstanceId,
useViewportMatch,
useReducedMotion,
} from '@wordpress/compose';
import { Notice } from '@wordpress/components';
import { useInstanceId, useViewportMatch } from '@wordpress/compose';
import { store as preferencesStore } from '@wordpress/preferences';
import {
BlockBreadcrumb,
Expand Down Expand Up @@ -80,8 +72,6 @@ const interfaceLabels = {
header: __( 'Editor top bar' ),
};

const ANIMATION_DURATION = 0.25;

export default function Editor( { isLoading } ) {
const {
record: editedPost,
Expand All @@ -92,7 +82,6 @@ export default function Editor( { isLoading } ) {
const { type: editedPostType } = editedPost;

const isLargeViewport = useViewportMatch( 'medium' );
const disableMotion = useReducedMotion();

const {
context,
Expand Down Expand Up @@ -292,37 +281,13 @@ export default function Editor( { isLoading } ) {
}
) }
header={
<AnimatePresence initial={ false }>
{ canvasMode === 'edit' && (
<motion.div
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main purpose of this PR is to move this animation within the "InterfaceSkeleton" component because the header is also animated there. So if these two animations are in two different places, they may cause conflicts (for instance the hover animation within the skeleton might trigger while the other animation is in progress...)

initial={ {
marginTop: -60,
} }
animate={ {
marginTop: 0,
} }
exit={ {
marginTop: -60,
} }
transition={ {
type: 'tween',
duration:
// Disable transition in mobile to emulate a full page transition.
disableMotion ||
! isLargeViewport
? 0
: ANIMATION_DURATION,
ease: [ 0.6, 0, 0.4, 1 ],
} }
>
<Header
setEntitiesSavedStatesCallback={
setEntitiesSavedStatesCallback
}
/>
</motion.div>
) }
</AnimatePresence>
canvasMode === 'edit' && (
<Header
setEntitiesSavedStatesCallback={
setEntitiesSavedStatesCallback
}
/>
)
}
actions={
<SavePublishPanels
Expand Down
33 changes: 24 additions & 9 deletions packages/editor/src/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,20 @@ import PostViewLink from '../post-view-link';
import PreviewDropdown from '../preview-dropdown';
import { store as editorStore } from '../../store';

const slideY = {
hidden: { y: '-50px' },
distractionFreeInactive: { y: 0 },
hover: { y: 0, transition: { type: 'tween', delay: 0.2 } },
const toolbarVariations = {
distractionFreeDisabled: { y: '-50px' },
distractionFreeHover: { y: 0 },
distractionFreeHidden: { y: '-50px' },
visible: { y: 0 },
hidden: { y: 0 },
};

const backButtonVariations = {
distractionFreeDisabled: { x: '-100%' },
distractionFreeHover: { x: 0 },
distractionFreeHidden: { x: '-100%' },
visible: { x: 0 },
hidden: { x: 0 },
};

function Header( {
Expand Down Expand Up @@ -81,11 +91,16 @@ function Header( {
// as some plugins might be relying on its presence.
return (
<div className="editor-header edit-post-header">
<BackButton.Slot />
<motion.div
variants={ slideY }
transition={ { type: 'tween', delay: 0.8 } }
variants={ backButtonVariations }
transition={ { type: 'tween' } }
>
<BackButton.Slot />
</motion.div>
<motion.div
variants={ toolbarVariations }
className="editor-header__toolbar"
transition={ { type: 'tween' } }
>
<DocumentTools
disableBlockTools={ forceDisableBlockTools || isTextEditor }
Expand All @@ -112,8 +127,8 @@ function Header( {
</div>
</motion.div>
<motion.div
variants={ slideY }
transition={ { type: 'tween', delay: 0.8 } }
variants={ toolbarVariations }
transition={ { type: 'tween' } }
className="editor-header__settings"
>
{ ! customSaveButton && ! isPublishSidebarOpened && (
Expand Down
94 changes: 60 additions & 34 deletions packages/interface/src/components/interface-skeleton/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import {
import NavigableRegion from '../navigable-region';

const ANIMATION_DURATION = 0.25;
const commonTransition = {
type: 'tween',
duration: ANIMATION_DURATION,
ease: [ 0.6, 0, 0.4, 1 ],
};

function useHTMLClass( className ) {
useEffect( () => {
Expand All @@ -42,12 +47,30 @@ function useHTMLClass( className ) {
}

const headerVariants = {
hidden: { opacity: 0 },
hover: {
hidden: { opacity: 1, marginTop: -60 },
visible: { opacity: 1, marginTop: 0 },
distractionFreeHover: {
opacity: 1,
transition: { type: 'tween', delay: 0.2, delayChildren: 0.2 },
marginTop: 0,
transition: {
...commonTransition,
delay: 0.2,
delayChildren: 0.2,
},
},
distractionFreeHidden: {
opacity: 0,
marginTop: -60,
},
distractionFreeDisabled: {
opacity: 0,
marginTop: 0,
transition: {
...commonTransition,
delay: 0.8,
delayChildren: 0.8,
},
},
distractionFreeInactive: { opacity: 1, transition: { delay: 0 } },
};

function InterfaceSkeleton(
Expand Down Expand Up @@ -114,36 +137,39 @@ function InterfaceSkeleton(
) }
>
<div className="interface-interface-skeleton__editor">
{ !! header && (
<NavigableRegion
as={ motion.div }
className="interface-interface-skeleton__header"
aria-label={ mergedLabels.header }
initial={
isDistractionFree
? 'hidden'
: 'distractionFreeInactive'
}
whileHover={
isDistractionFree
? 'hover'
: 'distractionFreeInactive'
}
animate={
isDistractionFree
? 'hidden'
: 'distractionFreeInactive'
}
variants={ headerVariants }
transition={
isDistractionFree
? { type: 'tween', delay: 0.8 }
: undefined
}
>
{ header }
</NavigableRegion>
) }
<AnimatePresence initial={ false }>
{ !! header && (
<NavigableRegion
as={ motion.div }
className="interface-interface-skeleton__header"
aria-label={ mergedLabels.header }
initial={
isDistractionFree
? 'distractionFreeHidden'
: 'hidden'
}
whileHover={
isDistractionFree
? 'distractionFreeHover'
: 'visible'
}
animate={
isDistractionFree
? 'distractionFreeDisabled'
: 'visible'
}
exit={
isDistractionFree
? 'distractionFreeHidden'
: 'hidden'
}
variants={ headerVariants }
transition={ defaultTransition }
>
{ header }
</NavigableRegion>
) }
</AnimatePresence>
{ isDistractionFree && (
<div className="interface-interface-skeleton__header">
{ editorNotices }
Expand Down
Loading