Skip to content

Commit

Permalink
Reorganise
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Jul 20, 2020
1 parent d4bc33e commit 4a50096
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 104 deletions.
187 changes: 89 additions & 98 deletions packages/block-editor/src/components/block-list/insertion-point.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,30 @@ import Inserter from '../inserter';
import { getClosestTabbable } from '../writing-flow';
import { getBlockDOMNode } from '../../utils/dom';

function Indicator( { clientId } ) {
const showInsertionPoint = useSelect(
function InsertionPointInserter( {
clientId,
setIsInserterForced,
containerRef,
} ) {
const ref = useRef();
// Hide the inserter above the selected block and during multi-selection.
const isInserterHidden = useSelect(
( select ) => {
const {
getBlockIndex,
getBlockInsertionPoint,
isBlockInsertionPointVisible,
getBlockRootClientId,
getMultiSelectedBlockClientIds,
getSelectedBlockClientId,
hasMultiSelection,
} = select( 'core/block-editor' );
const rootClientId = getBlockRootClientId( clientId );
const blockIndex = getBlockIndex( clientId, rootClientId );
const insertionPoint = getBlockInsertionPoint();
const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds();
const selectedBlockClientId = getSelectedBlockClientId();

return (
isBlockInsertionPointVisible() &&
insertionPoint.index === blockIndex &&
( insertionPoint.rootClientId || '' ) === rootClientId
);
return hasMultiSelection()
? multiSelectedBlockClientIds.includes( clientId )
: clientId === selectedBlockClientId;
},
[ clientId ]
);

if ( ! showInsertionPoint ) {
return null;
}

return (
<div className="block-editor-block-list__insertion-point-indicator" />
);
}

function InsertionPointPopover( {
clientId,
isInserterShown,
isInserterForced,
setIsInserterForced,
containerRef,
isInserterHidden,
} ) {
const ref = useRef();
const element = getBlockDOMNode( clientId );

function focusClosestTabbable( event ) {
const { clientX, clientY, target } = event;

Expand All @@ -71,14 +53,55 @@ function InsertionPointPopover( {

const targetRect = target.getBoundingClientRect();
const isReverse = clientY < targetRect.top + targetRect.height / 2;
const container = isReverse ? containerRef.current : element;
const blockNode = getBlockDOMNode( clientId );
const container = isReverse ? containerRef.current : blockNode;
const closest =
getClosestTabbable( element, true, container ) || element;
getClosestTabbable( blockNode, true, container ) || blockNode;
const rect = new window.DOMRect( clientX, clientY, 0, 16 );

placeCaretAtVerticalEdge( closest, isReverse, rect, false );
}

return (
/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
<div
ref={ ref }
onFocus={ () => setIsInserterForced( true ) }
onBlur={ () => setIsInserterForced( false ) }
onClick={ focusClosestTabbable }
// While ideally it would be enough to capture the
// bubbling focus event from the Inserter, due to the
// characteristics of click focusing of `button`s in
// Firefox and Safari, it is not reliable.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
tabIndex={ -1 }
className={ classnames(
'block-editor-block-list__insertion-point-inserter',
{
'is-inserter-hidden': isInserterHidden,
}
) }
>
<Inserter
position="bottom center"
clientId={ clientId }
__experimentalIsQuick
/>
</div>
);
}

function InsertionPointPopover( {
clientId,
isInserterShown,
isInserterForced,
setIsInserterForced,
containerRef,
showInsertionPoint,
} ) {
const element = getBlockDOMNode( clientId );

return (
<Popover
noArrow
Expand All @@ -93,73 +116,45 @@ function InsertionPointPopover( {
className="block-editor-block-list__insertion-point"
style={ { width: element?.offsetWidth } }
>
<Indicator clientId={ clientId } />
{ showInsertionPoint && (
<div className="block-editor-block-list__insertion-point-indicator" />
) }
{ ( isInserterShown || isInserterForced ) && (
/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
<div
ref={ ref }
onFocus={ () => setIsInserterForced( true ) }
onBlur={ () => setIsInserterForced( false ) }
onClick={ focusClosestTabbable }
// While ideally it would be enough to capture the
// bubbling focus event from the Inserter, due to the
// characteristics of click focusing of `button`s in
// Firefox and Safari, it is not reliable.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
tabIndex={ -1 }
className={ classnames(
'block-editor-block-list__insertion-point-inserter',
{
'is-inserter-hidden': isInserterHidden,
}
) }
>
<Inserter
position="bottom center"
clientId={ clientId }
__experimentalIsQuick
/>
</div>
<InsertionPointInserter
clientId={ clientId }
setIsInserterForced={ setIsInserterForced }
containerRef={ containerRef }
/>
) }
</div>
</Popover>
);
}

export default function InsertionPoint( {
hasMultiSelection,
selectedBlockClientId,
children,
containerRef,
} ) {
export default function InsertionPoint( { children, containerRef } ) {
const [ isInserterShown, setIsInserterShown ] = useState( false );
const [ isInserterForced, setIsInserterForced ] = useState( false );
const [ inserterClientId, setInserterClientId ] = useState( null );
const {
multiSelectedBlockClientIds,
isMultiSelecting,
isInserterVisible,
selectedClientId,
} = useSelect( ( select ) => {
const {
getMultiSelectedBlockClientIds,
isMultiSelecting: _isMultiSelecting,
isBlockInsertionPointVisible,
getBlockInsertionPoint,
getBlockOrder,
} = select( 'core/block-editor' );

const insertionPoint = getBlockInsertionPoint();
const order = getBlockOrder( insertionPoint.rootClientId );

return {
isMultiSelecting: _isMultiSelecting(),
multiSelectedBlockClientIds: getMultiSelectedBlockClientIds(),
isInserterVisible: isBlockInsertionPointVisible(),
selectedClientId: order[ insertionPoint.index ],
};
}, [] );
const { isMultiSelecting, isInserterVisible, selectedClientId } = useSelect(
( select ) => {
const {
isMultiSelecting: _isMultiSelecting,
isBlockInsertionPointVisible,
getBlockInsertionPoint,
getBlockOrder,
} = select( 'core/block-editor' );

const insertionPoint = getBlockInsertionPoint();
const order = getBlockOrder( insertionPoint.rootClientId );

return {
isMultiSelecting: _isMultiSelecting(),
isInserterVisible: isBlockInsertionPointVisible(),
selectedClientId: order[ insertionPoint.index ],
};
},
[]
);

function onMouseMove( event ) {
if (
Expand Down Expand Up @@ -207,10 +202,6 @@ export default function InsertionPoint( {
setInserterClientId( clientId );
}

// Hide the inserter above the selected block and during multi-selection.
const isInserterHidden = hasMultiSelection
? multiSelectedBlockClientIds.includes( inserterClientId )
: inserterClientId === selectedBlockClientId;
const isVisible = isInserterShown || isInserterForced || isInserterVisible;

return (
Expand All @@ -224,7 +215,7 @@ export default function InsertionPoint( {
isInserterForced={ isInserterForced }
setIsInserterForced={ setIsInserterForced }
containerRef={ containerRef }
isInserterHidden={ isInserterHidden }
showInsertionPoint={ isInserterVisible }
/>
) }
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,7 @@ function RootContainer( { children, className }, ref ) {
const [ blockNodes, setBlockNodes ] = useState( {} );

return (
<InsertionPoint
hasMultiSelection={ hasMultiSelection }
selectedBlockClientId={ selectedBlockClientId }
containerRef={ ref }
>
<InsertionPoint containerRef={ ref }>
<BlockNodes.Provider value={ blockNodes }>
<BlockPopover />
<div
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/components/block-list/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@

// Hide the inserter above the selected block.
&.is-inserter-hidden .block-editor-inserter__toggle {
opacity: 0;
visibility: hidden;
pointer-events: none;
}
}
Expand Down

0 comments on commit 4a50096

Please sign in to comment.