Skip to content

Adding automatic scrolling on item focus for non-virtualized collections#2232

Merged
LFDanLu merged 7 commits into
mainfrom
issue_2156
Aug 24, 2021
Merged

Adding automatic scrolling on item focus for non-virtualized collections#2232
LFDanLu merged 7 commits into
mainfrom
issue_2156

Conversation

@LFDanLu
Copy link
Copy Markdown
Member

@LFDanLu LFDanLu commented Aug 19, 2021

Closes #2156
Essentially shifts some useSelectableList logic to useSelectableCollection.

Note that this doesn't handle the shift tabbing issue yet, that will be in a separate PR for discussion (#2233)

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

There are a couple new stories (useComboBox, useTabList, and useTable) that have non-virtualized collections. Test and make sure that keyboard navigation scrolls items into view as you focus them
Some interactions to try:

  • typeahead
  • arrow key navigation (make sure the focused key is always scrolled into view when hitting up/down)
  • home/end/pg up/pg down

🧢 Your Project:

RSP

allows non virtualized tables/grids created with useTable/useGrid to have automatic scrolling when moving focus via arrow keys
some components will have a ref that is not the same element as the scrollable region so add a prop for scrollRef
Comment on lines +305 to +307
listStyle: "none",
maxHeight: "150px",
overflow: "auto"
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the async example in useComboBox docs will now scroll, also is a good thing to add to the example since people will most likely want to limit the listbox height

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add this to the useSelect example as well? The listbox there should be identical I believe.

import {useFilter} from '@react-aria/i18n';
import {useListBox, useOption} from '@react-aria/listbox';

export function ComboBox(props) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can essentially ignore this code, copy pasta'd from our aria hook example. If we feel the docs example is sufficient for testing I can remove this, but feels useful for when we wanna test some more hook specific behavior in the future (e.g. non virtualized combobox)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this. I think we should probably have more stories for the docs example. Also helps us ensure TS actually passes 😉

// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// If not virtualized, scroll the focused element into view when the focusedKey changes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code below is from useSelectableList

@adobe-bot
Copy link
Copy Markdown

Build successful! 🎉

</TableHeaderRow>
))}
</TableRowGroup>
<TableRowGroup ref={bodyRef} type="tbody" style={{display: 'block', overflow: 'auto', maxHeight: '200px'}}>
Copy link
Copy Markdown
Member Author

@LFDanLu LFDanLu Aug 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same code from the useTable aria example except for the changes to make the table body scrollable and changes to work with the useSelectableCollection changes

The table column positioning is messed up due to the display: block hence why this is in a story and not the docs.

Comment on lines +56 to +57
isVirtualized,
scrollRef: ref
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opinions on this? I added this here because end users could make their own TabList scrollable instead of following our collapse behavior

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah seems reasonable. I'm having a hard time imagining a virtualized tab list though. Maybe leave off that option for now?

let {tabListProps} = useTabList(props, state, ref);
return (
<div style={{height: '150px'}}>
<div {...tabListProps} ref={ref} style={{display: 'flex', borderBottom: '1px solid grey', maxWidth: '400px', overflow: 'auto'}}>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken from TabList aria example

Comment on lines +56 to +57
isVirtualized,
scrollRef: ref
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah seems reasonable. I'm having a hard time imagining a virtualized tab list though. Maybe leave off that option for now?

allowsTabNavigation = false
allowsTabNavigation = false,
isVirtualized,
scrollRef
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we default this to ref since they will be the same in many cases?

getRowText?: (key: Key) => string
getRowText?: (key: Key) => string,
/**
* The ref attached to the scrollable body. Used to provided automatic scrolling on item focus for non-virtualized grids.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* The ref attached to the scrollable body. Used to provided automatic scrolling on item focus for non-virtualized grids.
* The ref attached to the scrollable body. Used to provide automatic scrolling on item focus for non-virtualized grids.

/**
* Whether the TabList is contained in a virtual scroller.
*/
isVirtualized?: boolean
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this option for now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AHH, my bad forgot to remove it from the types

@adobe-bot
Copy link
Copy Markdown

Build successful! 🎉

Comment on lines +23 to +26
let lotsOfItems: any[] = [];
for (let i = 0; i < 50; i++) {
lotsOfItems.push({name: 'Item ' + i});
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to do anything with this, but a fast way to do this is

let lotsOfItems = (new Array(50)).map((_, i) => `Item ${i}` )

Copy link
Copy Markdown
Member

@snowystinger snowystinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm everything scrolling like i would think it should

@adobe-bot
Copy link
Copy Markdown

Build successful! 🎉

@LFDanLu LFDanLu merged commit 5360a76 into main Aug 24, 2021
@LFDanLu LFDanLu deleted the issue_2156 branch August 24, 2021 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support scrolling on focusedKey change in Table hooks

4 participants