-
Notifications
You must be signed in to change notification settings - Fork 986
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
Keyboard sorting #501
Keyboard sorting #501
Conversation
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.
Hey @b-ryu,
Thanks for taking the time to submit this PR! Left a few comments / questions / suggestions, I think this is going in the right direction, my main concern is with the way the elements are moved in the DOM currently, I'd prefer using transforms in order to offer the possibility to animate the elements as they shift positions.
On a separate note, I think it'd also be nice from an accessibility perspective to announce what is going on to assist users with visual (or other) impairments:
This doesn't have to happen in this PR, but something worth considering :)
6a82526
to
fb72278
Compare
Just want to say it's super encouraging to see signs of life with this library. Thanks @clauderic! I want to submit a PR that just moves to the new Context API (see: https://twitter.com/dan_abramov/status/1097866569701621763). I imagine it's a small PR but was worried it may not be accepted ever. Will try now! |
89cf923
to
c09fd51
Compare
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.
Hey @b-ryu,
This is looking great, tophatted a bunch of different scenarios and it works surprisingly well. You mentioned there were issues with react-infinite
, have you been able to replicate similar issues with the react-virtualized
or react-tiny-virtual-list
examples?
I've left a few questions / suggestions for now. I'll take a closer look at the logic for moving the items around over the weekend.
As an aside, I'm a bit worried about the amount of complexity and alternative code paths it introduces to the codebase, but that's probably more of a symptom of how the library currently works. In the future, I'd like to refactor the translations to be based on deterministic state updates and only have one code path for translates using getBoundingClientRect
to swap items around.
this.keyLift(event); | ||
} | ||
break; | ||
case KEYCODE.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.
This is probably a stretch for this PR, so let's keep it for a subsequent PR, but from a UX perspective, arrow up / down in a grid setup should probably move to the previous / next row
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.
@clauderic are there plans to include this functionality for up/down soon? I mean down arrow means swap element with element below in grid and similar for up arrow. Seems this is not possible at the moment
src/utils.js
Outdated
} else { | ||
return getScrollingElement(el.parentNode); | ||
} | ||
} |
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 is a nice addition, though sort of unrelated to the current PR as far as I can tell? Unless it's needed specifically for this PR, I'd prefer introducing it in a separate PR
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
First of all, I want to thank you for taking the time to review this PR (again) 😄👍
Not that I know of, the issue I mentioned seems only to arise when reaching the 300th or so item in a Update: fixed by using
Good point 👍 I initially considered inserting the logic for some of the key sorting methods into the existing methods since most of the underlying structure was the same, but found that it was a little messy, so I opted to share the ones I could use with minimal modification and extract the rest into their own set of methods.
Makes sense, caching the initial |
Just tested this out locally - awesome work! Really excited about this. I didn't look too closely at the code - my only comments though would have been nitpicky style changes for the examples 🙃 nothing to worry about! |
209eac1
to
705467a
Compare
src/SortableContainer/index.js
Outdated
// if (keyboard) { | ||
// // Adjust the nodes if the helper changes size | ||
// this.keyAnimateNodes(true); | ||
// } |
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 why this was needed, commented it out for the time being
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 was running into issues with correctly positioning the helper and the elements in the cases where there's resizing during sorting.
this.handleSortMove({ | ||
pageX: this.containerBoundingRect.left + edgeOffset.left, | ||
pageY: this.containerBoundingRect.top + edgeOffset.top, | ||
}); |
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 create a mock event here with the coordinates of where the mouse would be if this were a mouse event, so as to be able to re-use the logic for animating nodes. While the copy paste approach worked, it would have made maintaining and contributing to this library exponentially more challenging
fb8041e
to
2b54351
Compare
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.
Hey @b-ryu, great work on the refactor, this is looking really close to being ready to merge 👌
Gave this a fairly thorough tophat, it works great. There was only one small bug that I found with keyboard sorting of horizontal lists, it looks like there's an issue with the last index of the list, here's a gif demonstrating the issue:
I believe the same issue exists with mouse sorting actually, so might not be a huge deal for the time being.
src/utils.js
Outdated
} else { | ||
return getScrollingElement(el.parentNode); | ||
} | ||
} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
49307c4
to
00c773f
Compare
02be3ce
to
86852c9
Compare
86852c9
to
450e760
Compare
I am having trouble implementing this, and also hard to find examples on where Sorry for bringing up this PR, but docs are pretty minimal on accessibility support. Thanks in advance! |
It won't work at all, emmm... const GridItem = SortableElement(({ value }) => (
<div style={gridItemStyles} tabIndex={0}>
{value}
</div>
))
const Grid = SortableContainer(({ items }) => (
<div style={gridStyles}>
{items.map((col, index) => (
<GridItem key={col.key} index={index} value={col.title} tabIndex={0} />
))}
</div>
)) |
Resolves #77
This PR introduces keyboard-accessible sorting. Users are now able to sort items using only their keyboard.
Devs can set
tabIndex
on theirSortableElement
s. Once focused:Known issue(s)
On
react-infinite
, occasionally (every couple hundred items) it'll stop sorting prematurely, due to what I believe is the virtualized DOM not appending items to the list fast enough for the sorting to continue.The fix is simply to stop keyboard sorting, scroll down a bit with the mouse (or tab forward) and continue. Currently looking into possible solutions.The simplest fix that I found was just to increase the preload values passed toInfinite
's props, specificallypreloadBatchSize
andpreloadAdditionalHeight
.