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

Add a zoomed out view to the site editor #41156

Merged
merged 15 commits into from Sep 7, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference-guides/data/data-core-block-editor.md
Expand Up @@ -1492,7 +1492,7 @@ Action that enables or disables the navigation mode.

_Parameters_

- _isNavigationMode_ `string`: Enable/Disable navigation mode.
- _isNavigationMode_ `boolean`: Enable/Disable navigation mode.
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes! :)


### setTemplateValidity

Expand Down
12 changes: 12 additions & 0 deletions lib/experimental/editor-settings.php
Expand Up @@ -72,3 +72,15 @@ function gutenberg_initialize_editor( $editor_name, $editor_script_handle, $sett
);

}

/**
* Sets a global JS variable used to trigger the availability of zoomed out view.
*/
function gutenberg_enable_zoomed_out_view() {
$gutenberg_experiments = get_option( 'gutenberg-experiments' );
if ( $gutenberg_experiments && array_key_exists( 'gutenberg-zoomed-out-view', $gutenberg_experiments ) ) {
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableZoomedOutView = true', 'before' );
}
}

add_action( 'admin_init', 'gutenberg_enable_zoomed_out_view' );
12 changes: 12 additions & 0 deletions lib/experiments-page.php
Expand Up @@ -40,6 +40,18 @@ function gutenberg_initialize_experiments_settings() {
'gutenberg_display_experiment_section',
'gutenberg-experiments'
);

add_settings_field(
'gutenberg-zoomed-out-view',
__( 'Zoomed out view ', 'gutenberg' ),
'gutenberg_display_experiment_field',
'gutenberg-experiments',
'gutenberg_experiments_section',
array(
'label' => __( 'Test a new zoomed out view on the site editor (Warning: The new feature is not ready. You may experience UX issues that are being addressed)', 'gutenberg' ),
'id' => 'gutenberg-zoomed-out-view',
)
);
register_setting(
'gutenberg-experiments',
'gutenberg-experiments'
Expand Down
2 changes: 1 addition & 1 deletion packages/base-styles/_z-index.scss
Expand Up @@ -82,7 +82,7 @@ $z-layers: (
".block-editor-block-contextual-toolbar": 61,

// Ensures content overlay appears higher than resize containers used for image/video/etc.
".block-editor-block-content-overlay__overlay": 10,
".block-editor-block-list__block.has-block-overlay": 10,

// Query block setup state.
".block-editor-block-pattern-setup .pattern-slide": 100,
Expand Down
1 change: 0 additions & 1 deletion packages/block-editor/README.md
Expand Up @@ -717,7 +717,6 @@ _Parameters_
- _props_ `Object`: Optional. Props to pass to the element. Must contain the ref if one is defined.
- _options_ `Object`: Options for internal use only.
- _options.\_\_unstableIsHtml_ `boolean`:
- _options.\_\_unstableIsDisabled_ `boolean`: Whether the block should be disabled.

_Returns_

Expand Down
Expand Up @@ -11,14 +11,10 @@ import { store as blockEditorStore } from '../../store';
export default function useBlockOverlayActive( clientId ) {
return useSelect(
( select ) => {
const { isBlockSelected, hasSelectedInnerBlock, canEditBlock } =
const { __unstableHasActiveBlockOverlayActive } =
select( blockEditorStore );

return (
! canEditBlock( clientId ) ||
( ! isBlockSelected( clientId ) &&
! hasSelectedInnerBlock( clientId, true ) )
);
return __unstableHasActiveBlockOverlayActive( clientId );
},
[ clientId ]
);
Expand Down
@@ -1,4 +1,6 @@
.block-editor-block-content-overlay {
.block-editor-block-list__block.has-block-overlay {
cursor: default;

&::before {
content: "";
position: absolute;
Expand All @@ -9,11 +11,30 @@
background: transparent;
border: none;
border-radius: $radius-block-ui;
z-index: z-index(".block-editor-block-content-overlay__overlay");
z-index: z-index(".block-editor-block-list__block.has-block-overlay");
}

&::after {
content: none !important;
}

&:hover:not(.is-dragging-blocks)::before {
background: rgba(var(--wp-admin-theme-color--rgb), 0.1);
background: rgba(var(--wp-admin-theme-color--rgb), 0.3);
box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color) inset;
}

&.is-selected:not(.is-dragging-blocks)::before {
box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color) inset;
}

.block-editor-block-list__block {
pointer-events: none;
}

.block-editor-iframe__body.is-zoomed-out &::before {
// Unfortunately because of the vw unit, this is not always going to be exact
// When the scrollbar is visible, the frame exceeds the canvas by a few pixels.
width: calc(100vw);
left: calc(( 100% - 100vw ) / 2);
}
}
45 changes: 27 additions & 18 deletions packages/block-editor/src/components/block-list-appender/index.js
Expand Up @@ -6,7 +6,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { withSelect } from '@wordpress/data';
import { useSelect } from '@wordpress/data';
import { getDefaultBlockName } from '@wordpress/blocks';

/**
Expand All @@ -18,14 +18,35 @@ import { store as blockEditorStore } from '../../store';

function BlockListAppender( {
rootClientId,
canInsertDefaultBlock,
isLocked,
renderAppender: CustomAppender,
className,
selectedBlockClientId,
tagName: TagName = 'div',
} ) {
if ( isLocked || CustomAppender === false ) {
const { hideInserter, canInsertDefaultBlock, selectedBlockClientId } =
useSelect(
( select ) => {
const {
canInsertBlockType,
getTemplateLock,
getSelectedBlockClientId,
__unstableGetEditorMode,
} = select( blockEditorStore );

return {
hideInserter:
!! getTemplateLock( rootClientId ) ||
__unstableGetEditorMode() === 'zoom-out',
canInsertDefaultBlock: canInsertBlockType(
getDefaultBlockName(),
rootClientId
),
selectedBlockClientId: getSelectedBlockClientId(),
};
},
[ rootClientId ]
);

if ( hideInserter || CustomAppender === false ) {
return null;
}

Expand Down Expand Up @@ -92,16 +113,4 @@ function BlockListAppender( {
);
}

export default withSelect( ( select, { rootClientId } ) => {
const { canInsertBlockType, getTemplateLock, getSelectedBlockClientId } =
select( blockEditorStore );

return {
isLocked: !! getTemplateLock( rootClientId ),
canInsertDefaultBlock: canInsertBlockType(
getDefaultBlockName(),
rootClientId
),
selectedBlockClientId: getSelectedBlockClientId(),
};
} )( BlockListAppender );
export default BlockListAppender;
8 changes: 4 additions & 4 deletions packages/block-editor/src/components/block-list/index.js
Expand Up @@ -34,15 +34,15 @@ export const IntersectionObserver = createContext();
function Root( { className, ...settings } ) {
const [ element, setElement ] = useState();
const isLargeViewport = useViewportMatch( 'medium' );
const { isOutlineMode, isFocusMode, isNavigationMode } = useSelect(
const { isOutlineMode, isFocusMode, editorMode } = useSelect(
( select ) => {
const { getSettings, isNavigationMode: _isNavigationMode } =
const { getSettings, __unstableGetEditorMode } =
select( blockEditorStore );
const { outlineMode, focusMode } = getSettings();
return {
isOutlineMode: outlineMode,
isFocusMode: focusMode,
isNavigationMode: _isNavigationMode(),
editorMode: __unstableGetEditorMode(),
};
},
[]
Expand Down Expand Up @@ -74,7 +74,7 @@ function Root( { className, ...settings } ) {
className: classnames( 'is-root-container', className, {
'is-outline-mode': isOutlineMode,
'is-focus-mode': isFocusMode && isLargeViewport,
'is-navigate-mode': isNavigationMode,
'is-navigate-mode': editorMode === 'navigation',
} ),
},
settings
Expand Down
31 changes: 20 additions & 11 deletions packages/block-editor/src/components/block-list/style.scss
Expand Up @@ -13,15 +13,8 @@
.block-editor-block-list__layout {
position: relative;

// Select tool/navigation mode shows the default cursor until an additional click edits.
&.is-navigate-mode {
cursor: default;
}

// The primary indicator of selection in text is the native selection marker.
// When selecting multiple blocks, we provide an additional selection indicator.
&.is-navigate-mode .block-editor-block-list__block.is-selected,
&.is-navigate-mode .block-editor-block-list__block.is-hovered,
.block-editor-block-list__block.is-multi-selected:not(.is-partially-selected),
.block-editor-block-list__block.is-highlighted,
.block-editor-block-list__block.is-highlighted ~ .is-multi-selected {
Expand Down Expand Up @@ -58,10 +51,6 @@
}
}

&.is-navigate-mode .block-editor-block-list__block.is-hovered:not(.is-selected)::after {
box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color);
}

.block-editor-block-list__block.is-highlighted::after {
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
outline: $border-width solid transparent;
Expand Down Expand Up @@ -449,3 +438,23 @@
margin-bottom: auto;
}
}

/** Zoom Out mode styles **/
.block-editor-iframe__body {
transition: all 0.3s;
transform-origin: top center;

&.is-zoomed-out {
margin: 100px 0;
transform: scale(0.45);

// Add a bit more space between the top level blocks.
.wp-site-blocks > * + * {
margin-block-start: 2.5rem;
}

> .block-list-appender {
display: none;
}
}
}
Expand Up @@ -34,6 +34,7 @@ import { useNavModeExit } from './use-nav-mode-exit';
import { useBlockRefProvider } from './use-block-refs';
import { useIntersectionObserver } from './use-intersection-observer';
import { store as blockEditorStore } from '../../../store';
import useBlockOverlayActive from '../../block-content-overlay';

/**
* If the block count exceeds the threshold, we disable the reordering animation
Expand All @@ -50,18 +51,14 @@ const BLOCK_ANIMATION_THRESHOLD = 200;
* also pass any other props through this hook, and they will be merged and
* returned.
*
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Options for internal use only.
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Options for internal use only.
* @param {boolean} options.__unstableIsHtml
* @param {boolean} options.__unstableIsDisabled Whether the block should be disabled.
*
* @return {Object} Props to pass to the element to mark as a block.
*/
export function useBlockProps(
props = {},
{ __unstableIsHtml, __unstableIsDisabled = false } = {}
) {
export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
const {
clientId,
className,
Expand Down Expand Up @@ -114,6 +111,8 @@ export function useBlockProps(
[ clientId ]
);

const hasOverlay = useBlockOverlayActive( clientId );

// translators: %s: Type of block (i.e. Text, Image etc)
const blockLabel = sprintf( __( 'Block: %s' ), blockTitle );
const htmlSuffix = mode === 'html' && ! __unstableIsHtml ? '-visual' : '';
Expand All @@ -132,7 +131,7 @@ export function useBlockProps(
enableAnimation,
triggerAnimationOnChange: index,
} ),
useDisabled( { isDisabled: ! __unstableIsDisabled } ),
useDisabled( { isDisabled: ! hasOverlay } ),
] );

const blockEditContext = useBlockEditContext();
Expand All @@ -158,6 +157,7 @@ export function useBlockProps(
// The wp-block className is important for editor styles.
classnames( 'block-editor-block-list__block', {
'wp-block': ! isAligned,
'has-block-overlay': hasOverlay,
} ),
className,
props.className,
Expand Down
Expand Up @@ -31,15 +31,15 @@ function useInitialPosition( clientId ) {
( select ) => {
const {
getSelectedBlocksInitialCaretPosition,
isNavigationMode,
__unstableGetEditorMode,
isBlockSelected,
} = select( blockEditorStore );

if ( ! isBlockSelected( clientId ) ) {
return;
}

if ( isNavigationMode() ) {
if ( __unstableGetEditorMode() !== 'edit' ) {
return;
}

Expand Down
Expand Up @@ -26,8 +26,8 @@ function listener( event ) {
*/
export function useIsHovered() {
const isEnabled = useSelect( ( select ) => {
const { isNavigationMode, getSettings } = select( blockEditorStore );
return isNavigationMode() || getSettings().outlineMode;
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the effect of this change?

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually this seems to be related with this one: https://github.com/WordPress/gutenberg/pull/41156/files#diff-28c09e3ec5ce812113676dc711c85ce1c1596361ec12bdecc038adee432eb787R22, that actually change how the hover of other blocks is styled.

Trunk:

Screen.Recording.2022-08-29.at.5.20.49.PM.mov

Here:

Screen.Recording.2022-08-29.at.5.20.31.PM.mov

I'm not sure if that was discussed? Do you have any thoughts on this @jasmussen ?

const { getSettings } = select( blockEditorStore );
return getSettings().outlineMode;
}, [] );

return useRefEffect(
Expand Down