-
Notifications
You must be signed in to change notification settings - Fork 8
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
feat: add possibility nested dropdown #290
Conversation
Hello lebroz,My role is to assist you with the merge of this Status report is not available. |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: |
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.
Few comments below that we may want to address before merging this.
Another important fact I noticed is that the dropdown is not navigable through keyboard interactions (tab or directional arrows). It is not specific to this feature but this dropdown in dropdown implementation makes this an even farer goal to achieve, maybe it is something we should keep in mind as well when working on such features.
|
||
export type Item = { | ||
label: string, | ||
name?: string, | ||
selected?: boolean, | ||
onClick: any => void | ||
onClick?: any => void, |
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.
You might want to type this to SyntheticMouseEvent<HTMLDivElement>
(ref : https://flow.org/en/docs/react/events/)
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.
done
onBlur: any => void, | ||
onFocus: any => void, | ||
onClick: any => void, | ||
onMouseEnter: any => void, | ||
onMouseLeave: any => void, |
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.
You might want to type this to SyntheticMouseEvent (ref : https://flow.org/en/docs/react/events/)
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.
done
caret?: boolean | ||
caret?: boolean, | ||
dataIndex?: number, | ||
onClick?: any => void, |
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.
You might want to type this to SyntheticMouseEvent (ref : https://flow.org/en/docs/react/events/)
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.
done
src/lib/components/dropdown/utils.js
Outdated
else { | ||
// Check collision for dropdown acting as a root button* | ||
if (isBottomHit) { |
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.
nit: Please format this using prettier
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.
done
src/lib/components/dropdown/utils.js
Outdated
} | ||
} | ||
|
||
export const getPositionDropdownMenu = ({ isItem, triggerSize, size, nbItems, itemIndex }) => { |
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.
This method should be unit tested
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.
done
src/lib/components/dropdown/utils.js
Outdated
if (isRightHit && isBottomHit) { | ||
return css` | ||
right: ${size.width}px; | ||
bottom: ${-triggerSize.height * (itemIndex - nbItems + 1)}px; |
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.
What if some items takes more than one line ?
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.
@JBWatenbergScality Trying to find a solution but this one is a bit tricky to handle because indeed if an item have a height superior to other item, the new menu generated will display with a wrong offset. The problem I have to get each item size of the previous menu to place the new menu correctly but it will add a lot of complexity to the code. I can figure out a way to implement that in a simple way, do you have any suggestions ?
function Dropdown({ | ||
isItem = false, |
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.
I think separating exposed Dropdown component and an internal non-exposed DropdownAsAnItem component would be a better design. It would for example avoid confusion of having an isItem
or dataIndex
(which are implementation details) props available when trying to use the Dropdown component. I think it is very important to keep our exposed API very clear and not add props linked to the implementation in what we expose.
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.
done
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: The following reviewers are expecting changes from the author, or must review again: |
@@ -41,43 +63,19 @@ const DropdownMenuStyled = styled.ul` | |||
position: absolute; | |||
margin: 0; | |||
padding: 0; | |||
border: 1px solid ${getThemePropSelector("primary")}; |
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.
Please double-check with the design, we should have a border for each of the items.
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.
done
open={open} | ||
isItem={isItem} | ||
onMouseEnter={(e) => { | ||
setItemIndex(e && e.target && e.target.getAttribute('data-index') || 0) |
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.
We got a flow error. https://eslint.org/docs/rules/no-mixed-operators
setItemIndex(e && e.target && e.target.getAttribute('data-index')) || 0
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.
done
@@ -101,86 +99,125 @@ const Caret = styled.span` | |||
|
|||
const TriggerStyled = ButtonStyled.withComponent("div"); | |||
|
|||
const DropdownTriggerContainer = forwardRef<DropdownTriggerContainerProps, Element>(({isItem, dataIndex, open, size , variant, title, onBlur, onFocus, onClick, onMouseEnter, onMouseLeave, children, ...rest}, ref) => { |
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.
I am wondering do you have the prettier extension installed? Please enable it to make sure the code follows the .prettierrc
config.
Thanks!
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.
done
onClick: any => void | ||
onClick?: any => void, | ||
submenuIcon?: Node, | ||
submenuItems?: Array<Item> |
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.
As shown in the design, the documentation and support item also have another external link icon.
Maybe we miss another iconExternal
prop?
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.
done
<Caret> | ||
<i className="fas fa-caret-down" /> | ||
<i className={`fas fa-caret-${isItem ? 'right' : 'down'}`} /> |
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.
The right arrow icon should be chevron
instead of caret
<i className="fas fa-chevron-right" />
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.
done
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: The following reviewers are expecting changes from the author, or must review again: |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: The following reviewers are expecting changes from the author, or must review again: |
24480e9
to
abc113b
Compare
@JBWatenbergScality @ChengYanJin Regarding prettier, I think it is best to format the code before someone pushes his work. I just launch
What do you think ? |
…jest + simplify dropdown and fix menu position
here's a video of a demo: https://user-images.githubusercontent.com/47044686/115277099-c37fb100-a13b-11eb-80bc-bb2687e69221.mp4 |
Component:
Dropdown
Description:
Add possibility to put a Dropdown as an item of Dropdown
Design:
https://user-images.githubusercontent.com/47044686/115277099-c37fb100-a13b-11eb-80bc-bb2687e69221.mp4
Closes: #277