Unverified Commit db64a9a6 authored by Marcos Iglesias's avatar Marcos Iglesias Committed by GitHub

feat: Adds text alignment and row height options to the reusable table (#642)

* Adding row height and styling polishing
Signed-off-by: 's avatarMarcos Iglesias <miglesiasvalle@lyft.com>

* Adds header and column alignment options
Signed-off-by: 's avatarMarcos Iglesias <miglesiasvalle@lyft.com>

* Fixing betterer issue
Signed-off-by: 's avatarMarcos Iglesias <miglesiasvalle@lyft.com>
parent a58a7917
...@@ -99,8 +99,8 @@ exports[`strict null compilation`] = { ...@@ -99,8 +99,8 @@ exports[`strict null compilation`] = {
[255, 6, 11, "No overload matches this call.\\n The last overload gave the following error.\\n Type \'(() => SubmitSearchRequest) | null\' is not assignable to type \'ActionCreator<any>\'.\\n Type \'null\' is not assignable to type \'ActionCreator<any>\'.", "2296208050"], [255, 6, 11, "No overload matches this call.\\n The last overload gave the following error.\\n Type \'(() => SubmitSearchRequest) | null\' is not assignable to type \'ActionCreator<any>\'.\\n Type \'null\' is not assignable to type \'ActionCreator<any>\'.", "2296208050"],
[270, 4, 18, "No overload matches this call.\\n The last overload gave the following error.\\n Argument of type \'(dispatch: any, ownProps: any) => ActionCreator<unknown>\' is not assignable to parameter of type \'DispatchFromProps\'.\\n Type \'(dispatch: any, ownProps: any) => ActionCreator<unknown>\' is missing the following properties from type \'DispatchFromProps\': submitSearch, onInputChange, onSelectInlineResult", "2926224796"] [270, 4, 18, "No overload matches this call.\\n The last overload gave the following error.\\n Argument of type \'(dispatch: any, ownProps: any) => ActionCreator<unknown>\' is not assignable to parameter of type \'DispatchFromProps\'.\\n Type \'(dispatch: any, ownProps: any) => ActionCreator<unknown>\' is missing the following properties from type \'DispatchFromProps\': submitSearch, onInputChange, onSelectInlineResult", "2926224796"]
], ],
"js/components/common/Table/index.tsx:4167447816": [ "js/components/common/Table/index.tsx:1963290118": [
[47, 20, 7, "Type \'unknown\' is not assignable to type \'ReactNode\'.\\n Type \'unknown\' is not assignable to type \'ReactPortal\'.", "3446393192"] [121, 18, 7, "Type \'unknown\' is not assignable to type \'ReactNode\'.\\n Type \'unknown\' is not assignable to type \'ReactPortal\'.", "3446393192"]
], ],
"js/components/common/Tags/TagInput/index.tsx:3754832290": [ "js/components/common/Tags/TagInput/index.tsx:3754832290": [
[63, 22, 6, "Type \'undefined\' is not assignable to type \'GetAllTagsRequest\'.", "1979467425"], [63, 22, 6, "Type \'undefined\' is not assignable to type \'GetAllTagsRequest\'.", "1979467425"],
......
...@@ -7,11 +7,13 @@ import ShimmeringResourceLoader from '../ShimmeringResourceLoader'; ...@@ -7,11 +7,13 @@ import ShimmeringResourceLoader from '../ShimmeringResourceLoader';
import './styles.scss'; import './styles.scss';
type TextAlignmentValues = 'left' | 'right' | 'center';
export interface TableColumn { export interface TableColumn {
title: string; title: string;
field: string; field: string;
horAlign?: TextAlignmentValues;
// className?: string; // className?: string;
// horAlign?: 'left' | 'right' | 'center';
// width?: number; // width?: number;
// sortable?: bool (false) // sortable?: bool (false)
// data?: () => React.ReactNode ((row,index) => <div>{index}</div>) // data?: () => React.ReactNode ((row,index) => <div>{index}</div>)
...@@ -22,6 +24,7 @@ export interface TableOptions { ...@@ -22,6 +24,7 @@ export interface TableOptions {
tableClassName?: string; tableClassName?: string;
isLoading?: boolean; isLoading?: boolean;
numLoadingBlocks?: number; numLoadingBlocks?: number;
rowHeight?: number;
} }
export interface TableProps { export interface TableProps {
...@@ -32,13 +35,23 @@ export interface TableProps { ...@@ -32,13 +35,23 @@ export interface TableProps {
const DEFAULT_EMPTY_MESSAGE = 'No Results'; const DEFAULT_EMPTY_MESSAGE = 'No Results';
const DEFAULT_LOADING_ITEMS = 3; const DEFAULT_LOADING_ITEMS = 3;
const DEFAULT_ROW_HEIGHT = 30;
const DEFAULT_TEXT_ALIGNMENT = 'left';
type RowStyles = {
height: string;
};
type EmptyRowProps = { type EmptyRowProps = {
colspan: number; colspan: number;
rowStyles: RowStyles;
}; };
const EmptyRow: React.FC<EmptyRowProps> = ({ colspan }: EmptyRowProps) => ( const EmptyRow: React.FC<EmptyRowProps> = ({
<tr className="ams-table-row"> colspan,
rowStyles,
}: EmptyRowProps) => (
<tr className="ams-table-row" style={rowStyles}>
<td className="ams-empty-message-cell" colSpan={colspan}> <td className="ams-empty-message-cell" colSpan={colspan}>
{DEFAULT_EMPTY_MESSAGE} {DEFAULT_EMPTY_MESSAGE}
</td> </td>
...@@ -76,22 +89,40 @@ const Table: React.FC<TableProps> = ({ ...@@ -76,22 +89,40 @@ const Table: React.FC<TableProps> = ({
tableClassName = '', tableClassName = '',
isLoading = false, isLoading = false,
numLoadingBlocks = DEFAULT_LOADING_ITEMS, numLoadingBlocks = DEFAULT_LOADING_ITEMS,
rowHeight = DEFAULT_ROW_HEIGHT,
} = options; } = options;
const fields = columns.map(({ field }) => field); const fields = columns.map(({ field }) => field);
const rowStyles = { height: `${rowHeight}px` };
let body: React.ReactNode = <EmptyRow colspan={fields.length} />; let body: React.ReactNode = (
<EmptyRow colspan={fields.length} rowStyles={rowStyles} />
);
if (data.length) { if (data.length) {
body = data.map((item, index) => { body = data.map((item, index) => {
return ( return (
<tr className="ams-table-row" key={`index:${index}`}> <tr className="ams-table-row" key={`index:${index}`} style={rowStyles}>
{Object.entries(item) {Object.entries(item)
.filter(([key]) => fields.includes(key)) .filter(([key]) => fields.includes(key))
.map(([, value], index) => ( .map(([key, value], index) => {
<td className="ams-table-cell" key={`index:${index}`}> const columnInfo = columns.find(({ field }) => field === key);
{value} const horAlign = columnInfo
</td> ? columnInfo.horAlign || DEFAULT_TEXT_ALIGNMENT
))} : DEFAULT_TEXT_ALIGNMENT;
const cellStyle = {
textAlign: `${horAlign}` as TextAlignmentValues,
};
return (
<td
className="ams-table-cell"
key={`index:${index}`}
style={cellStyle}
>
{value}
</td>
);
})}
</tr> </tr>
); );
}); });
...@@ -99,9 +130,17 @@ const Table: React.FC<TableProps> = ({ ...@@ -99,9 +130,17 @@ const Table: React.FC<TableProps> = ({
let header: React.ReactNode = ( let header: React.ReactNode = (
<tr> <tr>
{columns.map(({ title }, index) => { {columns.map(({ title, horAlign = DEFAULT_TEXT_ALIGNMENT }, index) => {
const cellStyle = {
textAlign: `${horAlign}` as TextAlignmentValues,
};
return ( return (
<th className="ams-table-heading-cell" key={`index:${index}`}> <th
className="ams-table-heading-cell"
key={`index:${index}`}
style={cellStyle}
>
{title} {title}
</th> </th>
); );
......
...@@ -30,15 +30,27 @@ $shimmer-block-width: 40%; ...@@ -30,15 +30,27 @@ $shimmer-block-width: 40%;
.ams-table-heading-cell { .ams-table-heading-cell {
height: $table-header-height; height: $table-header-height;
text-transform: uppercase; text-transform: uppercase;
&:first-child {
padding-left: $spacer-3;
}
&:last-child {
padding-right: $spacer-3;
}
} }
.ams-empty-message-cell { .ams-table-cell {
@extend %text-body-w3; &:first-child {
padding-left: $spacer-3;
}
color: $text-primary; &:last-child {
text-align: center; padding-right: $spacer-3;
}
} }
// Loading State
.ams-table-heading-loading-cell { .ams-table-heading-loading-cell {
padding: $spacer-1; padding: $spacer-1;
} }
...@@ -57,3 +69,11 @@ $shimmer-block-width: 40%; ...@@ -57,3 +69,11 @@ $shimmer-block-width: 40%;
height: $shimmer-block-height; height: $shimmer-block-height;
width: $shimmer-block-width; width: $shimmer-block-width;
} }
// Empty State
.ams-empty-message-cell {
@extend %text-body-w3;
color: $text-primary;
text-align: center;
}
...@@ -8,7 +8,12 @@ import StorySection from '../StorySection'; ...@@ -8,7 +8,12 @@ import StorySection from '../StorySection';
import Table from '.'; import Table from '.';
import TestDataBuilder from './testDataBuilder'; import TestDataBuilder from './testDataBuilder';
const { columns, data } = new TestDataBuilder().build(); const dataBuilder = new TestDataBuilder();
const { columns, data } = dataBuilder.build();
const {
columns: alignedColumns,
data: alignedData,
} = dataBuilder.withAlignedColumns().build();
const stories = storiesOf('Components/Table', module); const stories = storiesOf('Components/Table', module);
...@@ -23,5 +28,11 @@ stories.add('Table', () => ( ...@@ -23,5 +28,11 @@ stories.add('Table', () => (
<StorySection title="Loading Table"> <StorySection title="Loading Table">
<Table columns={[]} data={[]} options={{ isLoading: true }} /> <Table columns={[]} data={[]} options={{ isLoading: true }} />
</StorySection> </StorySection>
<StorySection title="Table with different column alignment">
<Table columns={alignedColumns} data={alignedData} />
</StorySection>
<StorySection title="Table with 50px row height">
<Table columns={columns} data={data} options={{ rowHeight: 50 }} />
</StorySection>
</> </>
)); ));
...@@ -50,6 +50,31 @@ function TestDataBuilder(config = {}) { ...@@ -50,6 +50,31 @@ function TestDataBuilder(config = {}) {
return new this.Klass(attr); return new this.Klass(attr);
}; };
this.withAlignedColumns = () => {
const attr = {
data: [...this.config.data],
columns: [
{
title: 'Name',
field: 'name',
horAlign: 'left',
},
{
title: 'Type',
field: 'type',
horAlign: 'center',
},
{
title: 'Value',
field: 'value',
horAlign: 'right',
},
],
};
return new this.Klass(attr);
};
this.withEmptyData = () => { this.withEmptyData = () => {
const attr = { const attr = {
data: [], data: [],
......
...@@ -5314,6 +5314,14 @@ ...@@ -5314,6 +5314,14 @@
"@emotion/unitless": "0.7.5", "@emotion/unitless": "0.7.5",
"@emotion/utils": "0.11.3", "@emotion/utils": "0.11.3",
"csstype": "^2.5.7" "csstype": "^2.5.7"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==",
"dev": true
}
} }
}, },
"@emotion/unitless": { "@emotion/unitless": {
...@@ -5370,6 +5378,14 @@ ...@@ -5370,6 +5378,14 @@
"@emotion/unitless": "0.7.5", "@emotion/unitless": "0.7.5",
"@emotion/utils": "0.11.3", "@emotion/utils": "0.11.3",
"csstype": "^2.5.7" "csstype": "^2.5.7"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==",
"dev": true
}
} }
}, },
"@emotion/unitless": { "@emotion/unitless": {
...@@ -5479,6 +5495,14 @@ ...@@ -5479,6 +5495,14 @@
"@emotion/unitless": "0.7.5", "@emotion/unitless": "0.7.5",
"@emotion/utils": "0.11.3", "@emotion/utils": "0.11.3",
"csstype": "^2.5.7" "csstype": "^2.5.7"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==",
"dev": true
}
} }
}, },
"@emotion/unitless": { "@emotion/unitless": {
...@@ -5566,6 +5590,14 @@ ...@@ -5566,6 +5590,14 @@
"@emotion/unitless": "0.7.5", "@emotion/unitless": "0.7.5",
"@emotion/utils": "0.11.3", "@emotion/utils": "0.11.3",
"csstype": "^2.5.7" "csstype": "^2.5.7"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==",
"dev": true
}
} }
}, },
"@emotion/unitless": { "@emotion/unitless": {
...@@ -7913,6 +7945,14 @@ ...@@ -7913,6 +7945,14 @@
"@emotion/unitless": "0.7.5", "@emotion/unitless": "0.7.5",
"@emotion/utils": "0.11.3", "@emotion/utils": "0.11.3",
"csstype": "^2.5.7" "csstype": "^2.5.7"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==",
"dev": true
}
} }
}, },
"@emotion/unitless": { "@emotion/unitless": {
...@@ -9329,6 +9369,14 @@ ...@@ -9329,6 +9369,14 @@
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"csstype": "^2.2.0" "csstype": "^2.2.0"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==",
"dev": true
}
} }
}, },
"@types/react-redux": { "@types/react-redux": {
...@@ -13295,6 +13343,13 @@ ...@@ -13295,6 +13343,13 @@
"csstype": "^2.5.2", "csstype": "^2.5.2",
"stylis": "^3.5.0", "stylis": "^3.5.0",
"stylis-rule-sheet": "^0.0.10" "stylis-rule-sheet": "^0.0.10"
},
"dependencies": {
"csstype": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz",
"integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A=="
}
} }
}, },
"create-hash": { "create-hash": {
...@@ -13565,7 +13620,7 @@ ...@@ -13565,7 +13620,7 @@
}, },
"css-select": { "css-select": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
"dev": true, "dev": true,
"requires": { "requires": {
...@@ -13684,11 +13739,6 @@ ...@@ -13684,11 +13739,6 @@
} }
} }
}, },
"csstype": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
"integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
},
"currently-unhandled": { "currently-unhandled": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
...@@ -14094,7 +14144,7 @@ ...@@ -14094,7 +14144,7 @@
"dependencies": { "dependencies": {
"domelementtype": { "domelementtype": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
"dev": true "dev": true
} }
...@@ -20570,6 +20620,16 @@ ...@@ -20570,6 +20620,16 @@
"walker": "^1.0.7" "walker": "^1.0.7"
}, },
"dependencies": { "dependencies": {
"fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.6.0"
}
},
"fsevents": { "fsevents": {
"version": "1.2.9", "version": "1.2.9",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
...@@ -21121,6 +21181,16 @@ ...@@ -21121,6 +21181,16 @@
"yallist": "^3.0.0" "yallist": "^3.0.0"
} }
}, },
"minizlib": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.9.0"
}
},
"mkdirp": { "mkdirp": {
"version": "0.5.5", "version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
...@@ -21146,7 +21216,9 @@ ...@@ -21146,7 +21216,9 @@
"optional": true, "optional": true,
"requires": { "requires": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.8.6", "minipass": "^2.8.6",
"minizlib": "^1.2.1",
"mkdirp": "^0.5.0", "mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.3" "yallist": "^3.0.3"
...@@ -33551,7 +33623,7 @@ ...@@ -33551,7 +33623,7 @@
"dependencies": { "dependencies": {
"json5": { "json5": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"dev": true, "dev": true,
"requires": { "requires": {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment