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

Add tableLayout prop to EuiTable, EuiBasicTable and EuiInMemoryTable #2697

Merged
merged 13 commits into from
Dec 20, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added `nested` glyph to `EuiIcon` ([#2707](https://github.com/elastic/eui/pull/2707))
- Added `tableLayout` prop to `EuiTable`, `EuiBasicTable` and `EuiInMemoryTable` to provide the option of auto layout ([#2697](https://github.com/elastic/eui/pull/2697))

## [`17.3.1`](https://github.com/elastic/eui/tree/v17.3.1)

Expand Down
223 changes: 223 additions & 0 deletions src-docs/src/views/tables/auto/auto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import React, { Component } from 'react';

import { createDataStore } from '../data_store';

import makeId from '../../../../../src/components/form/form_row/make_id';

import {
EuiBasicTable,
EuiButtonGroup,
EuiCallOut,
EuiLink,
EuiSpacer,
} from '../../../../../src/components';

/*
Example user object:

{
id: '1',
firstName: 'john',
lastName: 'doe',
github: 'johndoe',
dateOfBirth: Date.now(),
nationality: 'NL',
online: true
}

Example country object:

{
code: 'NL',
name: 'Netherlands',
flag: '🇳🇱'
}
*/

const store = createDataStore();

const columns = [
{
field: 'firstName',
name: 'First Name',
sortable: true,
truncateText: true,
'data-test-subj': 'firstNameCell',
mobileOptions: {
render: item => (
<span>
{item.firstName}{' '}
<EuiLink href="#" target="_blank">
{item.lastName}
</EuiLink>
</span>
),
header: false,
truncateText: false,
enlarge: true,
fullWidth: true,
},
},
{
field: 'lastName',
name: 'Last Name',
render: name => (
<EuiLink href="#" target="_blank">
{name}
</EuiLink>
),
mobileOptions: {
show: false,
},
},
{
field: 'github',
name: 'Github',
},
];

const customColumns = [
{
field: 'firstName',
name: 'First Name',
sortable: true,
truncateText: true,
'data-test-subj': 'firstNameCell',
width: '20%',
mobileOptions: {
render: item => (
<span>
{item.firstName}{' '}
<EuiLink href="#" target="_blank">
{item.lastName}
</EuiLink>
</span>
),
header: false,
truncateText: false,
enlarge: true,
fullWidth: true,
},
},
{
field: 'lastName',
name: 'Last Name',
render: name => (
<EuiLink href="#" target="_blank">
{name}
</EuiLink>
),
mobileOptions: {
show: false,
},
},
{
field: 'github',
name: 'Github',
},
];

const items = store.users.filter((user, index) => index < 10);

const getRowProps = item => {
const { id } = item;
return {
'data-test-subj': `row-${id}`,
className: 'customRowClass',
onClick: () => console.log(`Clicked row ${id}`),
};
};

const getCellProps = (item, column) => {
const { id } = item;
const { field } = column;
return {
className: 'customCellClass',
'data-test-subj': `cell-${id}-${field}`,
textOnly: true,
};
};

const idPrefix = makeId();

const toggleButtons = [
{
id: `${idPrefix}0`,
label: 'Fixed',
value: 'fixed',
},
{
id: `${idPrefix}1`,
label: 'Auto',
value: 'auto',
},
{
id: `${idPrefix}2`,
label: 'Custom',
value: 'custom',
},
];

export class Table extends Component {
constructor(props) {
super(props);
this.state = {
layout: 'fixed',
toggleIdSelected: `${idPrefix}0`,
};
}

onChange = optionId => {
this.setState({
toggleIdSelected: optionId,
layout: toggleButtons.find(x => x.id === optionId).value,
});
};

toggleTableLayout = () => {
this.setState(prevState => ({ autoLayout: !prevState.autoLayout }));
};

render() {
let callOutText;

switch (this.state.layout) {
case 'fixed':
callOutText = 'First Name has truncateText set to true';
break;
case 'auto':
callOutText =
'First Name has truncateText set to true which is not applied since tableLayout is set to auto';
cchaos marked this conversation as resolved.
Show resolved Hide resolved
break;
case 'custom':
callOutText =
'First Name has truncateText set to true and width set to 20%';
break;
}

return (
<div>
<EuiButtonGroup
legend="Table layout group"
options={toggleButtons}
idSelected={this.state.toggleIdSelected}
onChange={this.onChange}
/>
<EuiSpacer size="m" />
<EuiCallOut
size="s"
color={this.state.layout === 'auto' ? 'warning' : 'primary'}
title={callOutText}
/>
<EuiSpacer size="m" />
<EuiBasicTable
items={items}
columns={this.state.layout === 'custom' ? customColumns : columns}
tableLayout={this.state.layout === 'auto' ? 'auto' : 'fixed'}
rowProps={getRowProps}
cellProps={getCellProps}
/>
</div>
);
}
}
56 changes: 56 additions & 0 deletions src-docs/src/views/tables/auto/auto_section.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { GuideSectionTypes } from '../../../components';
import { renderToHtml } from '../../../services';
import { EuiCode } from '../../../../../src/components';

import { Table } from './auto';

const source = require('!!raw-loader!./auto');
const html = renderToHtml(Table);
const layoutSnippet = [
`<EuiBasicTable
columns={[
{ field: 'column1', name: 'Column 1' },
{ field: 'column2', name: 'Column 2' }
]}
tableLayout="auto"
/>
`,
`<EuiBasicTable
columns={[
{ field: 'column1', name: 'Column 1', truncateText: true, width: '20%' },
{ field: 'column2', name: 'Column 2' }
]}
tableLayout="fixed"
/>`,
];

export const section = {
title: 'Table layout',
source: [
{
type: GuideSectionTypes.JS,
code: source,
},
{
type: GuideSectionTypes.HTML,
code: html,
},
],
text: (
<div>
<p>
<EuiCode>EuiBasicTable</EuiCode> has a fixed layout by default. You can
change it to <EuiCode>auto</EuiCode> using the{' '}
<EuiCode>tableLayout</EuiCode> prop. Note that setting{' '}
<EuiCode>tableLayout</EuiCode> to <EuiCode>auto</EuiCode> prevents the{' '}
<EuiCode>truncateText</EuiCode> prop from working properly. If you want
to set different columns widths while still being able to use{' '}
<EuiCode>truncateText</EuiCode>, set the width of each column using the{' '}
<EuiCode>width</EuiCode> prop.
</p>
</div>
),
snippet: layoutSnippet,
demo: <Table />,
cchaos marked this conversation as resolved.
Show resolved Hide resolved
};
1 change: 1 addition & 0 deletions src-docs/src/views/tables/auto/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { section } from './auto_section';
9 changes: 9 additions & 0 deletions src-docs/src/views/tables/basic/props_info.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ export const propsInfo = {
required: false,
type: { name: '(criteria: #Criteria) => void' },
},
tableLayout: {
description:
'Sets the table-layout CSS property. Note that auto tableLayout prevents truncateText from working properly.',
required: false,
type: {
name: '(fixed | auto)',
},
defaultValue: { value: 'fixed' },
},
},
},
},
Expand Down
2 changes: 2 additions & 0 deletions src-docs/src/views/tables/tables_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import { EuiCode, EuiSpacer, EuiCallOut } from '../../../../src/components';

import { section as basicSection } from './basic';
import { section as autoSection } from './auto';
import { section as paginatedSection } from './paginated';
import { section as sortingSection } from './sorting';
import { section as selectionSection } from './selection';
Expand Down Expand Up @@ -55,6 +56,7 @@ export const TableExample = {
inMemorySearchSection,
inMemorySearchCallbackSection,
inMemoryCustomSortingSection,
autoSection,
mobileSection,
customSection,
],
Expand Down
Loading