-
Notifications
You must be signed in to change notification settings - Fork 29
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
Use vertical line as drop target indicator for plots #1935
Conversation
You modified the behaviour of drag and drop for other plots (Trends and Data Series), it should stay the same. If the test still fails after, this is shown here by the last drag in the video: Screen.Recording.2022-06-21.at.7.10.42.PM.mov |
There is a little bug when dropping on an invalid target. The column will stay dark: Screen.Recording.2022-06-21.at.7.15.48.PM.movOther than that, your implementation looks great. Great job! Getting around table behaviour is not an easy task. Like I said previously, be careful not to change the behaviour of drag and drop elsewhere (checkpoints and template plots and column headers in the table) and the PR will be pretty solid after that. |
@sroy3 Thank you for the feedback and help! I managed to fix both issues, and even added back the border that was missing for the drop target of Trends and Data Series. As such I'm marking this as ready for review :) |
Does using |
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.
Great work so far! I've found a couple tiny nitpicks from a first read-over, but it seems like all the big issues were caught by Stephanie and you've already handled them! I'll be taking another look early tomorrow.
style={(id === draggedId && { display: 'none' }) || draggable.props.style} | ||
style={ | ||
(id === draggedId && hideDragged && { display: 'none' }) || | ||
draggable.props.style | ||
} |
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 see it was like this before this PR, but is the value of this style prop not just a weirdly written ternary? i.e. id === draggedId && hideDragged ? {display: 'none'} : draggable.props.style
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.
Not sure in this particular case, but I think our linter favours this syntax over ternaries using ?
and :
sometimes.
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.
Agreed. I changed it to a ternary and ESLint seemed to be fine with it in this case.
const target = screen.getByTestId('drop-target') | ||
|
||
// eslint-disable-next-line testing-library/no-node-access | ||
expect(target.nextElementSibling?.id).toStrictEqual(plots[0].id) |
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 these just compare the elements' references? i.e. expect(target.nextElementSibling).toBe(plots[0])
Not super important, just makes things a tiny bit simpler. This understandably apes the existing implementation, so it's not like it comes from nowhere.
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.
Good point. I agree with comparing by reference instead of id 👍
className={styles.dropTargetIndicator} | ||
data-testid="comparison-drop-target-indicator" | ||
style={{ | ||
[direction.toLowerCase()]: -4 |
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.
Using the transformed value of an enum directly as a string makes me a little uneasy, though it's not like avoiding doing so makes the code that much more elegant.
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.
Something I've seen done in Elm on cases like this, since in Elm you can't derive a string from an enum, is a function that explicitly returns a string from an enum value. I thought about doing the same thing here, but it gave me "early optimization" vibes. Does team have any ideas or precedents in the code base for tackling this?
& > th { | ||
display: block; | ||
width: 100%; | ||
} |
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.
Does this still apply to anything? It seems like the drop target was turned into a div
in another part of the code, and changing a th
's display
seems like it would cause a lot more chaos if it were applying.
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.
Good catch. It is applying because the current implementation re-renders the dragged cell as the drop target, which in this case is a th
. The display: block
is indeed unnecessary, but the width: 100%
is there so the cell expands to fill the drop target.
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.
plots[1].id, | ||
plots[2].id | ||
]) | ||
const target = screen.getByTestId('drop-target') |
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'm a little uneasy about changing a test for template plots drag and drop while the feature is meant to change only the comparison table.
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.
Agreed. This should've been reverted in ba9c284 along with the other changes. It's done now.
It should be fine as of e2e8caf. Do you think the approach of special casing based on the
Fixed in 31aebcf. Initially I thought that was a nice touch, as I find the indicator a little hard to see when it's not between two elements, but after seeing what it looks like in your clip (Safari, I presume) I agree that it's not the best way to solve this.
I did initially, but only came across solutions like setting and re-setting the element's style on |
I managed to fix this in 42f369d. The solution boils down to changing the wrapper element back to a I also tried using |
One more thing: I see a |
Fixes #1604
This was a tricky one to do initially. My first idea was to simply change the DropTarget to a vertical line and change the dragged column to not be hidden, but that didn't work because the vertical line was still part of the table flow, meaning it would consume the entire width of a header.
My current approach passes the header element itself to DropTarget so it can render the header as well as the drop indicators.
Here's a video of how it looks: https://streamable.com/tgy6ew
TODO:
Known issues:
Indicator looks thicker when the target is the first or last column
This wasn't intended during development, and it happens as a quirk of the indicator appearing under the headers when it's sandwiched between two of them, making it look thinner. Personally I think this can be repurposed into a good thing, as the line being thicker serves as a more clear indicator in this case where the user is less likely to notice the indicator at all.
Invalid DOM tree
Due to the way the indicator is placed in the DOM, it generates a DOM tree that fails react-dom's check as a
div
is not supposed to be a child oftr
. I can't think of a way to get around this, as the indicator needs to be a child of the row to be appropriately placed.Test
should move a template plot from one type in another section of the same type and show two drop targets
failsI need some guidance for this one. I couldn't find the scenario it describes in storybook, and it also seems like it would no longer be relevant with the new Drop Target mechanism for plots, but I'm not entirely sure.