Skip to content

feat: Implement useTable state hook#24329

Merged
ling1726 merged 11 commits intomicrosoft:masterfrom
ling1726:feat/table-selection-hook
Aug 11, 2022
Merged

feat: Implement useTable state hook#24329
ling1726 merged 11 commits intomicrosoft:masterfrom
ling1726:feat/table-selection-hook

Conversation

@ling1726
Copy link
Contributor

@ling1726 ling1726 commented Aug 10, 2022

Implments a useTable state hook to support selection and sort.

Initially I tried this with @tanstack/react-table, but that library is incredibly generic and relies heavily on render functions which I would like to avoid (for now). That library is also enormous because it supports features that are currently not asked for in Fluent UI

image

Addresses #24226

@fabricteam
Copy link
Collaborator

fabricteam commented Aug 10, 2022

📊 Bundle size report

Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
188.925 kB
51.884 kB
react-components
react-components: FluentProvider & webLightTheme
32.876 kB
10.773 kB
🤖 This report was generated against a0cfab0e5f74e3a3bfa9c269fff574295042d7f2

@codesandbox-ci
Copy link

codesandbox-ci bot commented Aug 10, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 1b3f64a:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@size-auditor
Copy link

size-auditor bot commented Aug 10, 2022

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: a0cfab0e5f74e3a3bfa9c269fff574295042d7f2 (build)

@fabricteam
Copy link
Collaborator

fabricteam commented Aug 10, 2022

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1275 1267 5000
Button mount 978 970 5000
FluentProvider mount 1593 1586 5000
FluentProviderWithTheme mount 636 633 10
FluentProviderWithTheme virtual-rerender 584 600 10
FluentProviderWithTheme virtual-rerender-with-unmount 624 621 10
MakeStyles mount 1912 1933 50000
SpinButton mount 2513 2507 5000

@ling1726 ling1726 marked this pull request as ready for review August 11, 2022 07:38
@ling1726 ling1726 requested review from a team as code owners August 11, 2022 07:38
@Hotell
Copy link
Contributor

Hotell commented Aug 11, 2022

55kB of JS... wow. good call

Comment on lines +10 to +16
setSelected(s => {
if (s.size === items.length) {
return new Set<RowId>();
}

return new Set<RowId>(items.map((item, i) => getRowId(item, i)));
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
setSelected(s => {
if (s.size === items.length) {
return new Set<RowId>();
}
return new Set<RowId>(items.map((item, i) => getRowId(item, i)));
});
setSelected(current => (
current.size === items.length ? new Set<RowId>() : new Set<RowId>(items.map((item, i) => getRowId(item, i)))
));

Copy link
Contributor

@bsunderhus bsunderhus left a comment

Choose a reason for hiding this comment

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

Looks amazing to me! I'm totally in favour of delegating complex behaviours to hooks!

import { useMultipleSelection } from './useMultipleSelection';
import { useSingleSelection } from './useSingleSelection';

export function useSelection<TItem>(
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO, wouldn't this hook be a bad idea? I mean, ideally it would be better if the user directly called useMultipleSelection or useSingleSelection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, I don't like it now either, it's a part of this issue to decompose these

Comment on lines +118 to +121
<TableHeaderCell {...headerSortProps('file')}>File</TableHeaderCell>
<TableHeaderCell {...headerSortProps('author')}>Author</TableHeaderCell>
<TableHeaderCell {...headerSortProps('lastUpdated')}>Last updated</TableHeaderCell>
<TableHeaderCell {...headerSortProps('lastUpdate')}>Last update</TableHeaderCell>
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that looks nice 😎 👏🏻

toggleColumnSort,
headerSortProps: (columnId: ColumnId) => ({
sortDirection: sortColumn === columnId ? sortDirection : undefined,
onClick: () => toggleColumnSort(columnId),
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks wrong to me, as this callback should be somehow memoized

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is impossible, it's similar to creating factory functions for radio onChange handlers

@ling1726 ling1726 merged commit 851d0fd into microsoft:master Aug 11, 2022
@ling1726 ling1726 mentioned this pull request Aug 17, 2022
13 tasks
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.

5 participants