Skip to content

Instantly share code, notes, and snippets.

@keik
Last active July 17, 2019 01:20
Show Gist options
  • Save keik/f519222a7aa66247479580a87744cfbd to your computer and use it in GitHub Desktop.
Save keik/f519222a7aa66247479580a87744cfbd to your computer and use it in GitHub Desktop.
/**
* Hook of List UI state manager
* - filter
* - pagination
* - sort
*
* @flow
*/
export const useFunctionalList = ({ items, filterableColumns }) => {
const [listOpts, setListOpts] = React.useState({
page: 1,
per: 10,
query: '',
sortBy: null,
sortDirection: ''
});
const handleChangeFilter = (query: string) =>
setListOpts(s => ({ ...s, page: 1, query }));
const handleChangeSort = (sortBy: string, sortDirection: 'ASC' | 'DESC') =>
setListOpts(s => ({ ...s, sortBy, sortDirection }));
const handleChangePage = (page: number) => setListOpts(s => ({ ...s, page }));
const handleChangePer = (per: number) =>
setListOpts(s => ({ ...s, page: 1, per }));
const filteredItems = items.filter(row =>
filterableColumns.some(propName =>
(row[propName] || '').includes(listOpts.query)
)
);
const sortSign = listOpts.sortDirection === 'ASC' ? 1 : -1;
const showingItems = filteredItems
.sort((a, b) => {
if (listOpts.sortBy == null) return 0;
const av = a[listOpts.sortBy];
const bv = b[listOpts.sortBy];
return av === bv ? 0 : (av > bv ? 1 : -1) * sortSign;
})
.slice(listOpts.per * (listOpts.page - 1), listOpts.per * listOpts.page);
return {
filteredItems,
handleChangeFilter,
handleChangePage,
handleChangePer,
handleChangeSort,
listOpts,
showingItems
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment