-
Notifications
You must be signed in to change notification settings - Fork 9
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
Handling Dropdown content resize #70
Changes from 8 commits
7d88367
e5d9e5d
b8e54e2
58ce549
9c4fb47
ab6591c
15bcb92
79d087a
d4c97ff
4e476fd
8572d14
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 |
---|---|---|
|
@@ -9,9 +9,27 @@ import findNextFocusableItem from '../../helpers/find-next-focusable-item'; | |
const baseClass = 'dropdown'; | ||
|
||
class DropdownList extends React.PureComponent { | ||
state = { | ||
focusedElement: null | ||
}; | ||
constructor(props) { | ||
super(props); | ||
|
||
this.state = { | ||
focusedElement: (props.items[0] && props.items[0].itemId) || null, | ||
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. autofocus first item on component create |
||
itemsCount: props.items.length | ||
}; | ||
} | ||
|
||
static getDerivedStateFromProps(props, state) { | ||
if ( | ||
props.autoFocusOnItemsCountChange && | ||
props.items.length !== state.itemsCount | ||
) { | ||
return { | ||
focusedElement: (props.items[0] && props.items[0].itemId) || null, | ||
itemsCount: props.items.length | ||
}; | ||
} | ||
return null; | ||
} | ||
|
||
componentDidMount() { | ||
document.addEventListener('keydown', this.onKeydown); | ||
|
@@ -31,8 +49,9 @@ class DropdownList extends React.PureComponent { | |
this.handleArrowKeyUse(event); | ||
} | ||
|
||
if (keyCode === KeyCodes.enter) { | ||
this.handleEnterKeyUse(); | ||
if (this.isItemSelectKeyCode(keyCode)) { | ||
event.preventDefault(); | ||
this.handleSelectKeyUse(); | ||
} | ||
}; | ||
|
||
|
@@ -48,7 +67,7 @@ class DropdownList extends React.PureComponent { | |
return this.hoverCallbacks[itemKey]; | ||
}; | ||
|
||
handleEnterKeyUse = () => { | ||
handleSelectKeyUse = () => { | ||
const { focusedElement } = this.state; | ||
|
||
if (focusedElement !== null) { | ||
|
@@ -104,6 +123,16 @@ class DropdownList extends React.PureComponent { | |
); | ||
}; | ||
|
||
isItemSelectKeyCode = keyCode => { | ||
const { itemSelectKeyCodes } = this.props; | ||
|
||
if (itemSelectKeyCodes && itemSelectKeyCodes.includes(keyCode)) { | ||
return true; | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
scrollItems = () => { | ||
if (!this.listRef.current) { | ||
return; | ||
|
@@ -142,7 +171,14 @@ class DropdownList extends React.PureComponent { | |
listRef = React.createRef(); | ||
|
||
render() { | ||
const { className, items, getItemBody, ...restProps } = this.props; | ||
const { | ||
className, | ||
items, | ||
getItemBody, | ||
itemSelectKeyCodes, | ||
autoFocusOnItemsCountChange, | ||
...restProps | ||
} = this.props; | ||
|
||
const mergedClassNames = getMergedClassNames( | ||
styles[`${baseClass}__list`], | ||
|
@@ -188,7 +224,12 @@ class DropdownList extends React.PureComponent { | |
} | ||
|
||
DropdownList.propTypes = { | ||
autoFocusOnItemsCountChange: PropTypes.bool, | ||
className: PropTypes.string, | ||
defaultFocusedItemId: PropTypes.oneOfType([ | ||
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. Where this prop is used? I can't find it in the code. 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. leftover, good catch :) |
||
PropTypes.string, | ||
PropTypes.number | ||
]), | ||
items: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
className: PropTypes.string, | ||
|
@@ -205,7 +246,15 @@ DropdownList.propTypes = { | |
}) | ||
).isRequired, | ||
getItemBody: PropTypes.func, | ||
onScroll: PropTypes.func | ||
onScroll: PropTypes.func, | ||
/** | ||
* you can specify which key press should trigger list item select | ||
*/ | ||
itemSelectKeyCodes: PropTypes.arrayOf(PropTypes.number) | ||
}; | ||
|
||
DropdownList.defaultProps = { | ||
itemSelectKeyCodes: [KeyCodes.enter] | ||
}; | ||
|
||
export default DropdownList; |
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.
https://github.com/que-etc/resize-observer-polyfill
It has really good browsers support.