Skip to content
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

feat(component): allow state override of table select all checkbox #224

Merged
merged 1 commit into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 58 additions & 12 deletions packages/big-design/src/components/Table/Actions/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import { Pagination } from '../../Pagination';
import { Text } from '../../Typography';
import { TableItem, TablePagination, TableSelectable } from '../types';

import { StyledActions } from './styled';
import { StyledActions, StyledPaginationContainer } from './styled';

export interface ActionsProps<T> {
itemName?: string;
items: T[];
pagination?: TablePagination;
selectable?: TableSelectable<T>;
tableId: string;
}

export const Actions = memo(
<T extends TableItem>({ selectable, pagination, tableId, items = [], ...props }: ActionsProps<T>) => {
<T extends TableItem>({ selectable, pagination, tableId, itemName, items = [], ...props }: ActionsProps<T>) => {
const totalItems = pagination ? pagination.totalItems : items.length;

const handleSelectAll = () => {
if (!selectable) {
return;
Expand All @@ -31,20 +34,48 @@ export const Actions = memo(
}
};

const renderSelectAllAction = ({ itemType, selectedItems }: TableSelectable<T>) => {
const getSelectAllChecked = () => {
if (!selectable) {
return false;
}

const { selectAllState, selectedItems } = selectable;

switch (selectAllState) {
case 'ALL':
Copy link
Member

Choose a reason for hiding this comment

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

🍹 consider putting these strings in a constants definition or similar

return true;

case 'PARTIAL':
case 'NONE':
return false;

default:
const totalSelectedItems = selectedItems.length;
const totalItemsInPage = items.length;

return totalSelectedItems === totalItemsInPage && totalItemsInPage > 0;
}
};

const renderSelectAllAction = () => {
if (!selectable) {
return null;
}

const { selectAllState, selectedItems } = selectable;
const totalSelectedItems = selectedItems.length;
const totalItemsInPage = items.length;
const isChecked = totalSelectedItems === totalItemsInPage && totalItemsInPage > 0;
const isIndeterminate = totalSelectedItems > 0 && totalSelectedItems !== totalItemsInPage;

const isChecked = getSelectAllChecked();
const isIndeterminate =
selectAllState === 'PARTIAL' || (totalSelectedItems > 0 && totalSelectedItems !== totalItemsInPage);

return (
<Flex.Item flexGrow={2}>
<Flex.Item marginRight="xxSmall">
<Flex flexDirection="row">
<Checkbox isIndeterminate={isIndeterminate} checked={isChecked} onChange={handleSelectAll} />
<Text marginLeft="small">
{totalSelectedItems === 0
? `${totalItemsInPage} ${itemType}`
: `${totalSelectedItems}/${totalItemsInPage} ${itemType}`}
{totalSelectedItems === 0 ? `${totalItems}` : `${totalSelectedItems}/${totalItems}`}
</Text>
</Flex>
</Flex.Item>
Expand All @@ -54,13 +85,27 @@ export const Actions = memo(
const renderPagination = useMemo(
() =>
pagination && (
<Flex.Item style={{ marginLeft: 'auto' }}>
<StyledPaginationContainer>
<Pagination {...pagination} />
</Flex.Item>
</StyledPaginationContainer>
),
[pagination],
);

const renderItemName = () => {
if (typeof itemName !== 'string') {
return null;
}

const text = Boolean(selectable) ? itemName : `${totalItems} ${itemName}`;

return (
<Flex.Item>
<Text margin="none">{text}</Text>
</Flex.Item>
);
};

return (
<StyledActions
alignItems="center"
Expand All @@ -70,7 +115,8 @@ export const Actions = memo(
padding="small"
Copy link
Contributor

Choose a reason for hiding this comment

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

🍹Could you try and remove the style={{ marginLeft: 'auto' }} on the pagination, and add justifyContent="space-between" to StyledActions? We should try and clean up those style attributes.

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case, we have multiple actions, one of them being the itemName so if we do space-between we won't be getting what we want :(

However, I can move this to a custom-styled Flex.

We should add auto to MarginProps

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh yeah, well in that case maybe you could change the Flex.Item for both SelectAll and ItemName to have alignSelf="flex-start" and Pagination alignSelf="flex-end"? 🤷‍♀️

{...props}
>
{selectable && renderSelectAllAction(selectable)}
{renderSelectAllAction()}
{renderItemName()}
{renderPagination}
</StyledActions>
);
Expand Down
4 changes: 4 additions & 0 deletions packages/big-design/src/components/Table/Actions/styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ import styled from 'styled-components';
import { Flex } from '../../Flex';

export const StyledActions = styled(Flex)``;
export const StyledPaginationContainer = styled(Flex.Item)`
margin-left: auto;
`;

StyledActions.defaultProps = { theme: defaultTheme };
StyledPaginationContainer.defaultProps = { theme: defaultTheme };
11 changes: 9 additions & 2 deletions packages/big-design/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
className,
columns,
id,
itemName,
items,
keyField = 'id',
pagination,
Expand Down Expand Up @@ -62,7 +63,7 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
};

const shouldRenderActions = () => {
return Boolean(pagination) || Boolean(selectable);
return Boolean(pagination) || Boolean(selectable) || Boolean(itemName);
};

const getItemKey = (item: T, index: number): string | number => {
Expand Down Expand Up @@ -129,7 +130,13 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
return (
<>
{shouldRenderActions() && (
<Actions pagination={pagination} selectable={selectable} items={items} tableId={tableIdRef.current} />
<Actions
pagination={pagination}
selectable={selectable}
items={items}
itemName={itemName}
tableId={tableIdRef.current}
/>
)}
<StyledTable {...rest} id={tableIdRef.current}>
{renderHeaders()}
Expand Down
Loading