-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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 multi select #896
Add multi select #896
Changes from all commits
a687b81
1cb0e46
4ef611a
01d124a
cd04a65
ec368f5
91b577c
d489fce
336eade
236bf6f
6ef9c81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,11 +10,11 @@ import './style.scss'; | |
import Button from '../button'; | ||
import Dashicon from '../dashicon'; | ||
|
||
function IconButton( { icon, children, label, className, ...additionalProps } ) { | ||
function IconButton( { icon, children, label, className, focus, ...additionalProps } ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const classes = classnames( 'components-icon-button', className ); | ||
|
||
return ( | ||
<Button { ...additionalProps } aria-label={ label } className={ classes }> | ||
<Button { ...additionalProps } aria-label={ label } className={ classes } focus={ focus }> | ||
<Dashicon icon={ icon } /> | ||
{ children } | ||
</Button> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ function Toolbar( { controls } ) { | |
'is-active': control.isActive, | ||
} ) } | ||
aria-pressed={ control.isActive } | ||
focus={ focus && ! index } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is causing some trouble for me in tests. I am unsure as to what is happening here. Where is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. This was causing a bug too. Thanks for catching it! |
||
/> | ||
) ) } | ||
</ul> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { connect } from 'react-redux'; | ||
import clickOutside from 'react-click-outside'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import VisualEditorBlock from './block'; | ||
import { | ||
getBlockUids, | ||
getBlockInsertionPoint, | ||
getBlockSelectionStart, | ||
getBlockSelectionEnd, | ||
} from '../../selectors'; | ||
|
||
const INSERTION_POINT_PLACEHOLDER = '[[insertion-point]]'; | ||
|
||
class VisualEditorBlockList extends wp.element.Component { | ||
constructor( props ) { | ||
super( props ); | ||
|
||
this.onSelectionStart = this.onSelectionStart.bind( this ); | ||
this.onSelectionChange = this.onSelectionChange.bind( this ); | ||
this.onSelectionEnd = this.onSelectionEnd.bind( this ); | ||
|
||
this.state = { | ||
selectionAtStart: null, | ||
}; | ||
} | ||
|
||
onSelectionStart( uid ) { | ||
this.setState( { selectionAtStart: uid } ); | ||
} | ||
|
||
onSelectionChange( uid ) { | ||
const { onMultiSelect, selectionStart, selectionEnd } = this.props; | ||
const { selectionAtStart } = this.state; | ||
const isAtStart = selectionAtStart === uid; | ||
|
||
if ( ! selectionAtStart ) { | ||
return; | ||
} | ||
|
||
if ( isAtStart && selectionStart ) { | ||
onMultiSelect( { start: null, end: null } ); | ||
} | ||
|
||
if ( ! isAtStart && selectionEnd !== uid ) { | ||
onMultiSelect( { start: selectionAtStart, end: uid } ); | ||
} | ||
} | ||
|
||
onSelectionEnd() { | ||
this.setState( { selectionAtStart: null } ); | ||
} | ||
|
||
handleClickOutside() { | ||
this.props.clearSelectedBlock(); | ||
} | ||
|
||
render() { | ||
const { blocks, insertionPoint } = this.props; | ||
const insertionPointIndex = blocks.indexOf( insertionPoint ); | ||
const blocksWithInsertionPoint = insertionPoint | ||
? [ | ||
...blocks.slice( 0, insertionPointIndex + 1 ), | ||
INSERTION_POINT_PLACEHOLDER, | ||
...blocks.slice( insertionPointIndex + 1 ), | ||
] | ||
: blocks; | ||
|
||
return ( | ||
<div> | ||
{ blocksWithInsertionPoint.map( ( uid ) => { | ||
if ( uid === INSERTION_POINT_PLACEHOLDER ) { | ||
return ( | ||
<div | ||
key={ INSERTION_POINT_PLACEHOLDER } | ||
className="editor-visual-editor__insertion-point" | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<VisualEditorBlock | ||
key={ uid } | ||
uid={ uid } | ||
onSelectionStart={ () => this.onSelectionStart( uid ) } | ||
onSelectionChange={ () => this.onSelectionChange( uid ) } | ||
onSelectionEnd={ this.onSelectionEnd } | ||
/> | ||
); | ||
} ) } | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default connect( | ||
( state ) => ( { | ||
blocks: getBlockUids( state ), | ||
insertionPoint: getBlockInsertionPoint( state ), | ||
selectionStart: getBlockSelectionStart( state ), | ||
selectionEnd: getBlockSelectionEnd( state ), | ||
} ), | ||
( dispatch ) => ( { | ||
clearSelectedBlock: () => dispatch( { type: 'CLEAR_SELECTED_BLOCK' } ), | ||
onMultiSelect( { start, end } ) { | ||
dispatch( { type: 'MULTI_SELECT', start, end } ); | ||
}, | ||
} ) | ||
)( clickOutside( VisualEditorBlockList ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain the issues with focus you were seeing? Do we need to monitor this prop if it changes during the lifetime of the component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Circling back to this. I encountered the Toolbar
focus
prop when working on some unrelated refactoring and had no idea what its purpose is. I still don't, and could use some clarification as to this unanswered question.