This repository was archived by the owner on Mar 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 51
Virtualized table prototype #2339
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
f094e03
Virtualized table prototype
pompomon d5c553b
Update chengelog
pompomon 9e8c66e
Move row rendering to children API
pompomon 4aef4d3
Adding notes on CellMeasurer usage
pompomon fae5077
Replace react-virtualized Table with List
pompomon ddd0bc7
Description fix
pompomon 1d86517
Add accessibility props
pompomon ca0791f
Adding aria- labels for table examples
pompomon d49af14
fix navigation in virtualized table header and navigation to virtuali…
mituron 9efd849
small fix for row behavior
mituron dda1ebd
Refactoring + adding tabondex -1 to scrollparent
pompomon 18f01c1
acc fixes
mituron 548ad75
Adding known a11y issues for Tree and Table
pompomon 1d4a67c
Merge branch 'master' into pompomon/virtualized-table
pompomon f2d7457
Fix prettier bug
pompomon 41f3a5a
Merge branch 'pompomon/virtualized-table' of https://github.com/micro…
pompomon ad23569
Update CHANGELOG.md
pompomon 9e0bca4
PR comment fixes
pompomon aa56ea4
Merge branch 'pompomon/virtualized-table' of https://github.com/micro…
pompomon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| import { | ||
| gridCellBehavior, | ||
| gridHeaderCellBehavior, | ||
| gridNestedBehavior, | ||
| gridRowBehavior, | ||
| Table, | ||
| } from '@fluentui/react' | ||
| import * as React from 'react' | ||
| import { | ||
| AutoSizer, | ||
| List as ReactVirtualizedList, | ||
| ListRowRenderer, | ||
| ListProps, | ||
| } from 'react-virtualized' | ||
| import getItems from './itemsGenerator' | ||
|
|
||
| const { rows } = getItems() | ||
| const rowGetter = ({ index }) => { | ||
| return rows[index] | ||
| } | ||
|
|
||
| // Overrides ARIA attributes assigned by default, which break accessibility | ||
| const accessibilityListProperties: Partial<ListProps> = { | ||
| 'aria-label': '', | ||
| 'aria-readonly': undefined, | ||
| containerRole: 'presentation', | ||
| role: 'presentation', | ||
| } | ||
|
|
||
| const rowRenderer: ListRowRenderer = ({ index, style }) => { | ||
| const row = rows[index] | ||
| return ( | ||
| <Table.Row | ||
| style={style} | ||
| key={row.key} | ||
| accessibility={gridRowBehavior} | ||
| aria-rowindex={index + 1} | ||
| > | ||
| <Table.Cell {...row.items[0]} accessibility={gridCellBehavior} /> | ||
| <Table.Cell {...row.items[1]} accessibility={gridCellBehavior} /> | ||
| <Table.Cell {...row.items[2]} accessibility={gridCellBehavior} /> | ||
| <Table.Cell {...row.items[3]} accessibility={gridCellBehavior} /> | ||
| </Table.Row> | ||
| ) | ||
| } | ||
|
|
||
| const VirtualizedTablePrototype = () => ( | ||
| <AutoSizer disableHeight> | ||
| {({ width }) => ( | ||
| <Table accessibility={gridNestedBehavior} aria-rowcount={rows.length}> | ||
| <Table.Row header accessibility={gridRowBehavior} style={{ width }}> | ||
| <Table.Cell content="id" accessibility={gridHeaderCellBehavior} /> | ||
| <Table.Cell content="Name" accessibility={gridHeaderCellBehavior} /> | ||
| <Table.Cell content="Picture" accessibility={gridHeaderCellBehavior} /> | ||
| <Table.Cell content="Age" accessibility={gridHeaderCellBehavior} /> | ||
| </Table.Row> | ||
|
|
||
| <ReactVirtualizedList | ||
| disableHeader | ||
| height={400} | ||
| rowCount={rows.length} | ||
| width={width} | ||
| rowHeight={80} | ||
| rowGetter={rowGetter} | ||
| rowRenderer={rowRenderer} | ||
| overscanRowCount={5} | ||
| {...accessibilityListProperties} | ||
| /> | ||
| </Table> | ||
| )} | ||
| </AutoSizer> | ||
| ) | ||
|
|
||
| export default VirtualizedTablePrototype | ||
147 changes: 147 additions & 0 deletions
147
docs/src/prototypes/VirtualizedTable/VirtualizedTables.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| import { | ||
| Accordion, | ||
| gridCellBehavior, | ||
| gridHeaderCellBehavior, | ||
| gridNestedBehavior, | ||
| gridRowBehavior, | ||
| Table, | ||
| } from '@fluentui/react' | ||
| import * as React from 'react' | ||
| import { | ||
| AutoSizer, | ||
| List as ReactVirtualizedList, | ||
| WindowScroller, | ||
| ListProps, | ||
| ListRowRenderer, | ||
| } from 'react-virtualized' | ||
| import getItems from './itemsGenerator' | ||
|
|
||
| // Magic offset for native scrollbar in Edge on Mac | ||
| const scrollbarOffset = 10 | ||
pompomon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| function VirtualizedTablesPrototype() { | ||
| const [ref, setRef] = React.useState(null) | ||
|
|
||
| const tables = [ | ||
| { | ||
| key: 'table1', | ||
| title: <div>Table one</div>, | ||
| content: <VirtualizedTable scrollElementRef={ref} label={'table1'} />, | ||
| }, | ||
| { | ||
| key: 'table2', | ||
| title: <div>Custom table title</div>, | ||
| content: <VirtualizedTable scrollElementRef={ref} label={'table2'} />, | ||
| }, | ||
| ] | ||
|
|
||
| return ( | ||
| <div | ||
| id="scrollParent" | ||
| style={{ height: '700px', overflowY: 'auto' }} | ||
| ref={setRef} | ||
| tabIndex={-1} | ||
| role="none" | ||
| > | ||
| {ref && <Accordion panels={tables} />} | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| interface VirtualizedTableProps { | ||
| scrollElementRef: HTMLDivElement | ||
| label: string | ||
| } | ||
|
|
||
| const accessibilityListProperties: Partial<ListProps> = { | ||
| 'aria-label': '', | ||
| 'aria-readonly': undefined, | ||
| containerRole: 'presentation', | ||
| role: 'presentation', | ||
| tabIndex: null, | ||
| } | ||
|
|
||
| const accessibilityWrapperProperties: React.HTMLAttributes<HTMLDivElement> = { | ||
| 'aria-label': '', | ||
| 'aria-readonly': undefined, | ||
| role: 'presentation', | ||
| } | ||
|
|
||
| function VirtualizedTable(props: VirtualizedTableProps) { | ||
| const { header, rows } = getItems(20, 50) | ||
| const renderedItems = [header, ...rows] | ||
| const itemsCount = renderedItems.length | ||
|
|
||
| const rowGetter = ({ index }) => { | ||
| return renderedItems[index] | ||
| } | ||
|
|
||
| const rowRenderer: ListRowRenderer = ({ index, style }) => { | ||
| const row = renderedItems[index] | ||
| const header = row.key === 'header' | ||
| return ( | ||
| <Table.Row | ||
| style={style} | ||
| key={row.key} | ||
| accessibility={gridRowBehavior} | ||
pompomon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| aria-rowindex={index + 1} | ||
| header={header} | ||
| > | ||
| <Table.Cell | ||
| {...row.items[0]} | ||
| accessibility={header ? gridHeaderCellBehavior : gridCellBehavior} | ||
| /> | ||
| <Table.Cell | ||
| {...row.items[1]} | ||
| accessibility={header ? gridHeaderCellBehavior : gridCellBehavior} | ||
| /> | ||
| <Table.Cell | ||
| {...row.items[2]} | ||
| accessibility={header ? gridHeaderCellBehavior : gridCellBehavior} | ||
| /> | ||
| <Table.Cell | ||
| {...row.items[3]} | ||
| accessibility={header ? gridHeaderCellBehavior : gridCellBehavior} | ||
| /> | ||
| </Table.Row> | ||
| ) | ||
| } | ||
|
|
||
| return ( | ||
| <WindowScroller scrollElement={props.scrollElementRef} key={`${props.scrollElementRef}`}> | ||
| {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => ( | ||
| <AutoSizer disableHeight> | ||
| {({ width }) => { | ||
| return height ? ( | ||
| <Table | ||
| accessibility={gridNestedBehavior} | ||
| aria-rowcount={itemsCount} | ||
| aria-label={props.label} | ||
| > | ||
| <div ref={el => registerChild(el)} {...accessibilityWrapperProperties}> | ||
pompomon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <ReactVirtualizedList | ||
| autoHeight | ||
| disableHeader={true} | ||
| height={height} | ||
| rowCount={itemsCount} | ||
| width={width - scrollbarOffset} | ||
| onScroll={onChildScroll} | ||
| scrollTop={scrollTop} | ||
| rowHeight={80} | ||
| isScrolling={isScrolling} | ||
| rowGetter={rowGetter} | ||
| rowRenderer={rowRenderer} | ||
| overscanRowCount={20} | ||
| {...accessibilityListProperties} | ||
| /> | ||
| </div> | ||
| </Table> | ||
| ) : null | ||
| }} | ||
| </AutoSizer> | ||
| )} | ||
| </WindowScroller> | ||
| ) | ||
| } | ||
|
|
||
| export default VirtualizedTablesPrototype | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import * as React from 'react' | ||
| import VirtualizedTable from './VirtualizedTable' | ||
| import VirtualizedTables from './VirtualizedTables' | ||
| import { PrototypeSection, ComponentPrototype } from '../Prototypes' | ||
|
|
||
| export default () => ( | ||
| <PrototypeSection title="VirtualizedTable"> | ||
| <ComponentPrototype | ||
| title="Virtualized Table" | ||
| description="Single table with fixed header and its content virtualized using `react-virtualized`." | ||
| > | ||
| <VirtualizedTable /> | ||
| </ComponentPrototype> | ||
| <ComponentPrototype | ||
| title="Two virtualized tables in an accordion" | ||
| description={ | ||
| <> | ||
| <b>Notes:</b> | ||
| <br /> | ||
| <span> | ||
| Prototype is using fixed row height, for dynamic height please check{' '} | ||
| <a href="https://github.com/bvaughn/react-virtualized/tree/master/source/CellMeasurer"> | ||
| CellMeasurer component. | ||
| </a> | ||
| </span> | ||
| <br /> | ||
| <b>Known issues:</b> | ||
| <br /> | ||
| <b>Integration with React-custom-scrollbars. </b> | ||
| <span> | ||
| React-virtualized has{' '} | ||
| <a href="https://github.com/techniq/mui-downshift/issues/34"> | ||
| an opened feature request | ||
| </a>{' '} | ||
| to support React-custom-scrollbars and there are a couple of ways to add custom | ||
| scrollbars to List component (see{' '} | ||
| <a href="https://github.com/bvaughn/react-virtualized/issues/143">issue one</a> and{' '} | ||
| <a href="https://github.com/bvaughn/react-virtualized/issues/692">issue two</a>). | ||
| Unfortunately, suggested solutions do not seem to work with two lists wrapped with | ||
| WindowScroller elements. | ||
| </span> | ||
| </> | ||
| } | ||
| > | ||
| <VirtualizedTables /> | ||
| </ComponentPrototype> | ||
| </PrototypeSection> | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import * as _ from 'lodash' | ||
pompomon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| function getItems(minItems = 20, maxItems = 40) { | ||
| function getRandomNumber(minItems, maxItems) { | ||
| return _.random(minItems, maxItems) | ||
| } | ||
|
|
||
| function getRandomName() { | ||
| const names = ['Roman', 'Alex', 'Ali', 'Bo', 'Timbuktu', 'Daria', 'E.T.'] | ||
| const addLongName = Math.random() > 0.5 | ||
| return ( | ||
| names[Math.floor(Math.random() * names.length)] + | ||
| (addLongName ? ' van von der Longername' : '') | ||
| ) | ||
| } | ||
|
|
||
| function generateRows() { | ||
| const header = { | ||
| key: 'header', | ||
| items: [ | ||
| { content: 'id', key: 'id' }, | ||
| { content: 'Name', key: 'name' }, | ||
| { content: 'Picture', key: 'pic' }, | ||
| { content: 'Age', key: 'action' }, | ||
| ], | ||
| } | ||
| const rowsPlain = _.times(getRandomNumber(minItems, maxItems), index => ({ | ||
| key: `${index}`, | ||
| items: [ | ||
| { content: `${index}`, key: `${index}-1` }, | ||
| { | ||
| content: getRandomName(), | ||
| truncateContent: true, | ||
| key: `${index}-2`, | ||
| }, | ||
| { content: 'None', key: `${index}-3` }, | ||
| { content: `${getRandomNumber(10, 1000)} years`, key: `${index}-4` }, | ||
| ], | ||
| })) | ||
|
|
||
| return { header, rows: rowsPlain } | ||
| } | ||
|
|
||
| return generateRows() | ||
| } | ||
|
|
||
| export default getItems | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.