Skip to content

Commit

Permalink
Merge 1b80655 into 19339e0
Browse files Browse the repository at this point in the history
  • Loading branch information
jonambas committed Jun 1, 2020
2 parents 19339e0 + 1b80655 commit ae48578
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 19 deletions.
45 changes: 31 additions & 14 deletions packages/matchbox/src/components/Table/Table.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Cell, HeaderCell, Row } from './TableElements';
import styled from 'styled-components';
import { margin, padding, compose } from 'styled-system';
import { margin, padding } from 'styled-system';
import { createPropTypes } from '@styled-system/prop-types';
import { table } from './styles';
import { pick } from '@styled-system/props';
import { Box } from '../Box';
import { pick } from '../../helpers/systemProps';
import { Cell, HeaderCell, Row } from './TableElements';
import { TablePaddingContext } from './context';

const system = compose(margin, padding);
import { table, wrapper, sticky } from './styles';

const StyledTable = styled('table')`
${table}
${system}
${padding}
${sticky}
`;

const Wrapper = styled(Box)`
${wrapper}
${margin}
`;

function Table(props) {
const { children, data, ...rest } = props;
const { children, data, freezeFirstColumn, ...rest } = props;
const [isScrolled, setIsScrolled] = React.useState(false);

const handleScroll = React.useCallback(
e => {
setIsScrolled(e.target.scrollLeft > 10);
},
[freezeFirstColumn],
);

const dataMarkup = data ? (
<tbody>
Expand All @@ -28,14 +41,17 @@ function Table(props) {
children
);

const { px = '500', py = '400', ...context } = pick(rest);
const { px = '500', py = '400', ...paddingProps } = pick(rest, padding.propNames);
const marginProps = pick(rest, margin.propNames);

return (
<StyledTable {...rest}>
<TablePaddingContext.Provider value={{ px, py, ...context }}>
{dataMarkup}
</TablePaddingContext.Provider>
</StyledTable>
<Wrapper onScroll={freezeFirstColumn ? handleScroll : null} {...marginProps}>
<StyledTable freezeFirstColumn={freezeFirstColumn} isScrolled={isScrolled} {...rest}>
<TablePaddingContext.Provider value={{ px, py, ...paddingProps }}>
{dataMarkup}
</TablePaddingContext.Provider>
</StyledTable>
</Wrapper>
);
}

Expand All @@ -45,6 +61,7 @@ Table.Row = Row;

Table.displayName = 'Table';
Table.propTypes = {
freezeFirstColumn: PropTypes.bool,
data: PropTypes.array,
/**
* React node(s)
Expand Down
22 changes: 22 additions & 0 deletions packages/matchbox/src/components/Table/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ export const headerCell = () => `
font-weight: ${tokens.fontWeight_semibold};
`;

export const sticky = ({ isScrolled, freezeFirstColumn }) => {
return `
td:first-child, th:first-child {
${
freezeFirstColumn
? `
transition: box-shadow ${tokens.motionDuration_medium} ${tokens.motionEase_in_out};
position: sticky;
left: 0;
background: inherit;
`
: ''
}
${isScrolled ? `box-shadow: ${tokens.boxShadow_400};` : ''}
}
`;
};

export const cell = () => `
word-break: break-all;
`;
Expand All @@ -30,3 +48,7 @@ export const row = () => `
background: ${tokens.color_gray_100};
}
`;

export const wrapper = () => `
overflow: auto;
`;
19 changes: 19 additions & 0 deletions packages/matchbox/src/components/Table/tests/Table.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,25 @@ describe('Table', () => {
).toEqual('three');
});

it('should freeze a column', () => {
wrapper = subject({ freezeFirstColumn: true });
wrapper.simulate('scroll', { target: { scrollLeft: 11 } });
expect(wrapper.find('table')).toHaveStyleRule('position', 'sticky', {
modifier: 'th:first-child',
});
expect(wrapper.find('table')).toHaveStyleRule('position', 'sticky', {
modifier: 'td:first-child',
});
});

it('should distribute system props correctly', () => {
wrapper = subject({ p: '100', m: '100' });
expect(wrapper).toHaveStyleRule('margin', '100');
expect(wrapper).not.toHaveStyleRule('padding', '100');
expect(wrapper.find('table')).not.toHaveStyleRule('margin', '100');
expect(wrapper.find('table')).toHaveStyleRule('padding', '100');
});

describe('Cell', () => {
it('renders children', () => {
wrapper = shallow(<Table.Cell>children test</Table.Cell>);
Expand Down
18 changes: 13 additions & 5 deletions stories/layout/Table.stories.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react';
import { withInfo } from '@storybook/addon-info';
import { Table, Panel } from '@sparkpost/matchbox';
import { Table, Panel, Box } from '@sparkpost/matchbox';

export default {
title: 'Layout|Table',
};

const Node = () => <div>A react component</div>;
const Node = ({ children = 'A react component' }) => <Box minWidth="900">{children}</Box>;
const data = [
['A', 'B', 'C'],
[<Node />, <Node />, <Node />],
[1, 2, 3],
['Foo', 'Bar', 'Baz', 'Foo'],
[<Node />, <Node />, <Node />, <Node />],
[1, 2, 3, 4],
];

export const TableComponents = withInfo({ propTablesExclude: [Panel] })(() => (
Expand Down Expand Up @@ -45,6 +45,14 @@ export const WithSuppliedData = withInfo()(() => (
</Panel>
));

export const ResponsiveTable = withInfo()(() => (
<Box maxWidth="1100">
<Panel>
<Table p="200" data={data} freezeFirstColumn />
</Panel>
</Box>
));

export const SystemProps = withInfo()(() => (
<Panel>
<Table>
Expand Down
2 changes: 2 additions & 0 deletions unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,5 @@
- #424 - Adds new bool prop `disableResponsiveBehavior` to Tabs
- #415 - Adds new `Spinner` Component
- #435 - Fixes Tab `disableResponsiveBehavior` rule
- #412 - `Table` are now responsive and support freezing the first column with the
`freezeFirstColumn` prop

0 comments on commit ae48578

Please sign in to comment.