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

Experimenting with navigation and edit modes #3195

Closed
wants to merge 8 commits into from
Closed
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
2 changes: 1 addition & 1 deletion blocks/editable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ export default class Editable extends Component {
this.editor.selection.collapse( false );
}
} else if ( isActive ) {
this.editor.getBody().blur();
// this.editor.getBody().blur();
}
}

Expand Down
7 changes: 5 additions & 2 deletions blocks/library/image/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ class ImageBlock extends Component {
render() {
const { attributes, setAttributes, focus, setFocus, className, settings } = this.props;
const { url, alt, caption, align, id, href, width, height } = attributes;
const fallbackFocus = url ? 'caption' : 'upload';
const focused = focus ? ( focus.editable || fallbackFocus ) : null;

const availableSizes = this.getAvailableSizes();
const figureStyle = width ? { width } : {};
const isResizable = [ 'wide', 'full' ].indexOf( align ) === -1;
const uploadButtonProps = { isLarge: true };
const uploadButtonProps = { isLarge: true, focus: focused === 'media' };
const uploadFromFiles = ( event ) => mediaUpload( event.target.files, setAttributes );
const dropFiles = ( files ) => mediaUpload( files, setAttributes );

Expand Down Expand Up @@ -161,6 +163,7 @@ class ImageBlock extends Component {
className="wp-block-image__upload-button"
onChange={ uploadFromFiles }
accept="image/*"
focus={ focused === 'upload' ? true : null }
>
{ __( 'Upload' ) }
</FormFileUpload>
Expand Down Expand Up @@ -268,7 +271,7 @@ class ImageBlock extends Component {
tagName="figcaption"
placeholder={ __( 'Write caption…' ) }
value={ caption }
focus={ focus && focus.editable === 'caption' ? focus : undefined }
focus={ focused === 'caption' ? focus : undefined }
onFocus={ focusCaption }
onChange={ ( value ) => setAttributes( { caption: value } ) }
inlineToolbar
Expand Down
6 changes: 3 additions & 3 deletions components/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import { Component, createElement } from '@wordpress/element';
* Internal dependencies
*/
import './style.scss';

class Button extends Component {
constructor( props ) {
super( props );
this.setRef = this.setRef.bind( this );
}

componentDidMount() {
if ( this.props.focus ) {
componentWillReceiveProps( nextProps ) {
// consider blurring and improve checking here.
if ( this.props.focus !== nextProps.focus && nextProps.focus ) {
this.ref.focus();
}
}
Expand Down
18 changes: 16 additions & 2 deletions editor/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,25 @@ export function updateBlock( uid, updates ) {
};
}

export function focusBlock( uid, config ) {
export function focusBlock( uid ) {
return {
type: 'UPDATE_FOCUS',
uid,
config,
config: {
target: 'block',
options: { },
},
};
}

export function focusBlockEdit( uid, config ) {
return {
type: 'UPDATE_FOCUS',
uid,
config: {
target: 'blockEdit',
options: config || {},
},
};
}

Expand Down
16 changes: 9 additions & 7 deletions editor/block-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ class BlockToolbar extends Component {
}
}

export default connect( ( state ) => {
const block = getSelectedBlock( state );
export default connect(
( state ) => {
const block = getSelectedBlock( state );

return ( {
block,
mode: block ? getBlockMode( state, block.uid ) : null,
} );
} )( BlockToolbar );
return ( {
block,
mode: block ? getBlockMode( state, block.uid ) : null,
} );
}
)( BlockToolbar );
3 changes: 3 additions & 0 deletions editor/header/header-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,8 @@ export default connect(
( dispatch ) => ( {
undo: () => dispatch( { type: 'UNDO' } ),
redo: () => dispatch( { type: 'REDO' } ),
onFocusBlockEdit( uid, config ) {
dispatch( focusBlockEdit( uid, config ) );
},
} )
)( HeaderToolbar );
82 changes: 59 additions & 23 deletions editor/modes/visual-editor/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
clearSelectedBlock,
editPost,
focusBlock,
focusBlockEdit,
insertBlocks,
mergeBlocks,
removeBlock,
Expand All @@ -54,7 +55,7 @@ import {
getBlockMode,
} from '../../selectors';

const { BACKSPACE, ESCAPE, DELETE, ENTER, UP, RIGHT, DOWN, LEFT } = keycodes;
const { BACKSPACE, ESCAPE, DELETE, ENTER, TAB, UP, RIGHT, DOWN, LEFT } = keycodes;

class VisualEditorBlock extends Component {
constructor() {
Expand All @@ -81,7 +82,7 @@ class VisualEditorBlock extends Component {
}

componentDidMount() {
if ( this.props.focus ) {
if ( this.props.focus && this.props.focus.target === 'block' ) {
this.node.focus();
}

Expand Down Expand Up @@ -113,7 +114,7 @@ class VisualEditorBlock extends Component {
}

// Focus node when focus state is programmatically transferred.
if ( this.props.focus && ! prevProps.focus && ! this.node.contains( document.activeElement ) ) {
if ( this.props.focus !== prevProps.focus && this.props.focus && this.props.focus.target === 'block' ) {
this.node.focus();
}

Expand Down Expand Up @@ -225,8 +226,9 @@ class VisualEditorBlock extends Component {
}

onFocus( event ) {
const { onFocusBlock } = this.props;
if ( event.target === this.node ) {
this.props.onSelect();
onFocusBlock( this.props.uid );
}
}

Expand All @@ -249,24 +251,49 @@ class VisualEditorBlock extends Component {
}

onKeyDown( event ) {
const { keyCode, target } = event;
const { uid, onRemove, previousBlock, nextBlock, onFocusBlockEdit, onFocusBlock, focus } = this.props;

const { keyCode, target, shiftKey } = event;

const focusOnContainer = target === this.node;

switch ( keyCode ) {
case TAB:
if ( ! shiftKey && focus && focus.target === 'blockEdit' && nextBlock ) {
event.preventDefault();
event.stopPropagation();
onFocusBlockEdit( nextBlock.uid );
} else if ( shiftKey && focus && focus.target === 'blockEdit' && previousBlock ) {
event.preventDefault();
event.stopPropagation();
onFocusBlockEdit( previousBlock.uid );
}
break;
case ENTER:
// Insert default block after current block if enter and event
// not already handled by descendant.
if ( target === this.node ) {
if ( focusOnContainer ) {
event.preventDefault();

this.props.onInsertBlocks( [
createBlock( 'core/paragraph' ),
], this.props.order + 1 );
event.stopPropagation();
onFocusBlockEdit( this.props.uid );
}
break;

case UP:
case RIGHT:
if ( focusOnContainer && previousBlock ) {
event.preventDefault();
event.stopPropagation();
onFocusBlock( previousBlock.uid );
}
break;
case DOWN:
if ( focusOnContainer && nextBlock ) {
event.preventDefault();
event.stopPropagation();
onFocusBlock( nextBlock.uid );
}
break;
case RIGHT:
case LEFT:
// Arrow keys do not fire keypress event, but should still
// trigger typing mode.
Expand All @@ -276,20 +303,20 @@ class VisualEditorBlock extends Component {
case BACKSPACE:
case DELETE:
// Remove block on backspace.
if ( target === this.node ) {
if ( focusOnContainer ) {
event.preventDefault();
const { uid, onRemove, previousBlock, onFocus } = this.props;
onRemove( uid );

if ( previousBlock ) {
onFocus( previousBlock.uid, { offset: -1 } );
onFocusBlockEdit( previousBlock.uid, { offset: -1 } );
}
}
break;

case ESCAPE:
// Deselect on escape.
this.props.onDeselect();
if ( ! focusOnContainer ) {
onFocusBlock( this.props.uid );
}
break;
}
}
Expand Down Expand Up @@ -322,17 +349,22 @@ class VisualEditorBlock extends Component {

// Generate the wrapper class names handling the different states of the block.
const { isHovered, isSelected, isMultiSelected, isFirstMultiSelected, focus } = this.props;
const showUI = isSelected && ( ! this.props.isTyping || ( focus && focus.collapsed === false ) );

const isNavigating = focus && focus.target === 'block';

// Ignoring focus collapsed ... probably want to add that.
const showUI = isSelected && ( ! this.props.isTyping && focus && focus.target === 'blockEdit' );
const isProperlyHovered = isHovered && ! this.props.isSelecting;
const { error } = this.state;
const wrapperClassName = classnames( 'editor-visual-editor__block', {
'has-warning': ! isValid || !! error,
'is-selected': showUI,
'is-selected': isSelected && ! isNavigating,
'is-multi-selected': isMultiSelected,
'is-hovered': isProperlyHovered,
'is-navigating': isNavigating,
} );

const { onMouseLeave, onFocus, onReplace } = this.props;
const { onMouseLeave, onFocusBlockEdit, onReplace } = this.props;

// Determine whether the block has props to apply to the wrapper.
let wrapperProps;
Expand Down Expand Up @@ -383,12 +415,12 @@ class VisualEditorBlock extends Component {
<BlockCrashBoundary onError={ this.onBlockError }>
{ isValid && mode === 'visual' && (
<BlockEdit
focus={ focus }
focus={ focus && focus.target === 'blockEdit' ? focus.options : null }
attributes={ block.attributes }
setAttributes={ this.setAttributes }
insertBlocksAfter={ this.insertBlocksAfter }
onReplace={ onReplace }
setFocus={ partial( onFocus, block.uid ) }
setFocus={ partial( onFocusBlockEdit, block.uid ) }
mergeBlocks={ this.mergeBlocks }
className={ className }
id={ block.uid }
Expand Down Expand Up @@ -441,6 +473,10 @@ export default connect(
dispatch( updateBlockAttributes( uid, attributes ) );
},

onFocusBlock( uid ) {
dispatch( focusBlock( uid ) );
},

onSelect() {
dispatch( selectBlock( ownProps.uid ) );
},
Expand Down Expand Up @@ -475,8 +511,8 @@ export default connect(
dispatch( insertBlocks( blocks, position ) );
},

onFocus( ...args ) {
dispatch( focusBlock( ...args ) );
onFocusBlockEdit( uid, config ) {
dispatch( focusBlockEdit( uid, config ) );
},

onRemove( uid ) {
Expand Down
6 changes: 6 additions & 0 deletions editor/modes/visual-editor/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@
outline: 1px solid $light-gray-500;
}

/* This is a temporary addition to show navigation mode */
&.is-navigating:before {
outline: 2px solid darkblue;
transition: 0.2s outline;
}

// selection style for multiple blocks
&.is-multi-selected *::selection {
background: transparent;
Expand Down
12 changes: 9 additions & 3 deletions editor/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export function blockSelection( state = { start: null, end: null, focus: null, i
...state,
start: action.uid,
end: action.uid,
focus: action.focus || {},
focus: action.config || ( state.focus || {} ),
};
case 'UPDATE_FOCUS':
return {
Expand All @@ -379,7 +379,10 @@ export function blockSelection( state = { start: null, end: null, focus: null, i
return {
start: action.blocks[ 0 ].uid,
end: action.blocks[ 0 ].uid,
focus: {},
focus: {
target: 'blockEdit',
options: { },
},
isMultiSelecting: false,
};
case 'REPLACE_BLOCKS':
Expand All @@ -389,7 +392,10 @@ export function blockSelection( state = { start: null, end: null, focus: null, i
return {
start: action.blocks[ 0 ].uid,
end: action.blocks[ 0 ].uid,
focus: {},
focus: {
target: 'blockEdit',
options: { },
},
isMultiSelecting: false,
};
}
Expand Down
1 change: 1 addition & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ function gutenberg_register_vendor_scripts() {

// Vendor Scripts.
$react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix;
$react_suffix = '.development';

gutenberg_register_vendor_script(
'react',
Expand Down
24 changes: 24 additions & 0 deletions test/e2e/integration/003-focusing-blocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
describe( 'Focusing blocks', () => {
before( () => {
// cy.login();
cy.newPost();
} );

it( 'Testing focus of paragraph', () => {
cy.auditBlockFocus( 'Paragraph', () => {
cy.focused().type( 'Paragraph' );
} );
} );

it( 'Testing focus of image', () => {
cy.auditBlockFocus( 'Image', () => {
// cy.focused().type( 'Paragraph' );
} );
} );

it( 'Testing focus of heading', () => {
cy.auditBlockFocus( 'Heading', () => {
cy.focused().type( 'Heading' );
} );
} );
} );
Loading