-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Grid edit mode #2375
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
Grid edit mode #2375
Conversation
… when inside editable cell
|
Build successful! 🎉 |
…ahead if in edit mode
…edit mode also moved some edit mode logic out of keydowncapture in useGridCell and into useSelectableCollection so it is in a more general place
|
Build successful! 🎉 |
also stopping arrow keys from scrolling the table when edit mode is active. Not sure why page up/down/home/end still scroll if focused on a searchfield
| case 'Home': | ||
| if (delegate.getFirstKey) { | ||
| if (editModeEnabled) { | ||
| // Prevent scrolling from happening if in edit mode | ||
| // TODO: not sure why this doesn't stop table scrolling when in a searchfield in editmode... | ||
| e.preventDefault(); | ||
| } else if (delegate.getFirstKey) { |
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 believe this can be fixed with an approach like #1519, but will need to discuss if we want to prevent that behavior on all components that use useTextFields
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.
Additionally, scrolling will still happen if the user hits home/end when the cursor is at the start/end of the input text, I figure we will want to suppress that. Open to opinions
turns out we need the stop propagation so that row selection does not happen if you click on a textfield in a editable cell for the first time
|
Build successful! 🎉 |
| // TODO: should we support press events on textfield? | ||
| // This is added here so that pressing on a textfield in a table properly focuses the textfield | ||
| // and that selection doesn't trigger since usePress will stop propagation. However, usePress prevents default | ||
| // and thus stops text selection via mouse from working.... | ||
| // let {pressProps} = usePress({ | ||
| // ref | ||
| // }); | ||
| // The below is an alternative that allows the user to click into a textfield in a editable cell | ||
| let onPointerDown = (e) => { | ||
| ref.current.focus(); | ||
| e.stopPropagation(); | ||
| }; | ||
|
|
||
|
|
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.
Kinda iffy on this. If we don't manually focus the textfield on pointer down, clicking on a textfield in a tableview won't move focus into it. Buttons and other elements don't have this issue because they have usePress which manually focuses the element on pointer down, but we don't really want to use usePress in textfields because it will preventDefault and stop text selection via mouse.
Open to opinions on this, personally I want to have this focus behavior so that the user can do the following cases:
- click into a textfield in a tableview without needing to activate edit mode on the cell via keyboard first (this is consistent with how other components like buttons behave in a tableview right now)
- move focus between textfields in a tableview via clicking
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.
Yeah this feels weird though. It's not clear you're in edit mode and can't move focus out of the cell without pressing escape. 🤔
Let's gather more opinions here.
|
Build successful! 🎉 |
devongovett
left a comment
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.
initial comments
| } | ||
|
|
||
| let walker = getFocusableTreeWalker(ref.current); | ||
| let walker = getFocusableTreeWalker(ref.current, {tabbable: 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.
We could probably use createFocusManager here? It has focusNext and focusPrevious functions which are a bit nicer to work with than tree walker.
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.
Hrm, the ArrowLeft/ArrowRight logic relies on checking if the next element is a child node or not, but createFocusManager's focusNext and focusPrevious will attempt to focus stuff immediately
| state.selectionManager.setFocusedKey(node.key); | ||
| } | ||
|
|
||
| // Activating edit mode if user focuses a child of the editable cell (e.g. via click) |
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.
Still not sure about this one. It feels strange. You don't realize you're in edit mode at all... 🤔
| let {pressProps} = usePress({...itemProps, isDisabled}); | ||
|
|
||
| let containsEditCell = state.collection.getItem(state.editModeKey)?.parentKey === node.key; | ||
| if (containsEditCell) { |
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.
In #2363 I added an isDisabled prop to useSelectableItem which does the same thing as this. Could probably combine those.
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.
Sounds good, I'll pull the bare minimum isDisabled changes from that PR so it doesn't break behavior here
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.
Never mind, looking at it further it might be best if I wait till that PR goes in
Note to self regarding the change to be made:
- remove the if statement and its contents
- pass isDisabled to useSelectableItem if
containsEditCell
| /** | ||
| * Whether something in the collection is in edit mode and should disable typeahead and other collection keyboard behavior. | ||
| */ | ||
| editModeEnabled?: boolean |
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.
Maybe we can call this isDisabled? Not sure I want edit mode specific stuff to leak into the general useSelectableCollection since it's pretty grid specific...
| // TODO: should we support press events on textfield? | ||
| // This is added here so that pressing on a textfield in a table properly focuses the textfield | ||
| // and that selection doesn't trigger since usePress will stop propagation. However, usePress prevents default | ||
| // and thus stops text selection via mouse from working.... | ||
| // let {pressProps} = usePress({ | ||
| // ref | ||
| // }); | ||
| // The below is an alternative that allows the user to click into a textfield in a editable cell | ||
| let onPointerDown = (e) => { | ||
| ref.current.focus(); | ||
| e.stopPropagation(); | ||
| }; | ||
|
|
||
|
|
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.
Yeah this feels weird though. It's not clear you're in edit mode and can't move focus out of the cell without pressing escape. 🤔
Let's gather more opinions here.
| } | ||
|
|
||
| // If there is an active editable card, make sure it remains in the DOM even when scrolled out of view | ||
| // so that we don't lose the card's focused child. This really only matters for virtualized card view |
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.
Wonder how this affects screen readers. There'd be a gap in the rows that are "visible" potentially. We should test this.
| } = useFocusRing({within: true}); | ||
| let {isFocusVisible, focusProps} = useFocusRing(); | ||
| let {hoverProps, isHovered} = useHover({isDisabled}); | ||
| let containsEditCell = state.collection.getItem(state.editModeKey)?.parentKey === item.key; |
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.
Note to self:
If #2363 is merged with the useSelectableItem returning isPressed, perhaps we can get rid of the usePress above in TableRow? Will need to propagate isDisabled/containsEditCell through useTableRow -> useGridRow perhaps?
|
Build successful! 🎉 |
| // Prevent scrolling from happening if in edit mode | ||
| // TODO: not sure why this doesn't stop table scrolling when in a searchfield in editmode... | ||
| e.preventDefault(); |
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.
Can stop scrolling if we do something similar to #1519 and always prevent default on Home/End/PageUp/PageDown but we'd only want to do this if it were in a grid cell in edit mode...
Alternatively we could add Home/End/PageUp/PageDown cases to the keydown in useGridCell and prevent default if we are in edit mode but then this would disable default behavior of these keydowns on the child elements...
|
Closing for now, will revisit in the future |
Closes #2328
Some known issues:
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: