import { every, map, reverse, sortBy } from 'lodash'; import React from 'react'; import createReactClass from 'create-react-class'; import { Meta, Story } from '@storybook/react'; import { createClass } from '../../util/component-types'; import SuccessIcon from '../Icon/SuccessIcon/SuccessIcon'; import DataTable, { IDataTableProps } from './DataTable'; import TextField from '../TextField/TextField'; import CheckboxLabeled from '../CheckboxLabeled/CheckboxLabeled'; export default { title: 'Table/DataTable', component: DataTable, parameters: { docs: { description: { component: DataTable.peek.description, }, }, }, args: DataTable.defaultProps, } as Meta; function addKeys(children) { return map(children, (child, index) => ({ ...child, key: index })); } const Template: Story = (args) => ; const defaultColumns = addKeys([ ID , First , Last , E-Mail , Occupation , Salary , Status , ]); const defaultData = [ { id: 1, first_name: 'Isaac', last_name: 'Newton', email: 'inewton@example.com', occupation: 'Physicist', salary: '$100.01', status: , }, { id: 2, first_name: 'Albert', last_name: 'Einstein', email: 'aeinstein@example.com', occupation: 'Physicist', salary: '$100.02', status: , }, { id: 3, first_name: 'Leonardo', last_name: 'da Vinci', email: 'ldvinci@example.com', occupation: 'Engineer', salary: '$100.03', status: , }, { id: 4, first_name: 'Aristotle', last_name: null, email: 'aristotle@example.com', occupation: 'Tutor', salary: '$100.04', status: , }, { id: 5, first_name: 'Galileo', email: 'ggalilei@example.com', occupation: 'Physicist', salary: '$100.05', status: , }, { id: 6, first_name: 'Charles', last_name: 'Darwin', email: 'cdarwin@example.com', occupation: 'Biologist', salary: '$100.06', status: , }, { id: 7, first_name: 'Alexander', last_name: 'Macedon', email: 'amacedon@example.com', occupation: 'Head of State', salary: '$100.07', status: , }, { id: 8, first_name: 'Plato', last_name: 'Plato', email: 'plato@example.com', occupation: 'Philosopher', salary: '$100.08', status: , }, { id: 9, first_name: 'Mahatma', last_name: 'Gandhi', email: 'mgandhi@example.com', occupation: 'Politician', salary: '$100.09', status: , }, { id: 10, first_name: 'William', last_name: 'Shakespeare', email: 'wshakespear@example.com', occupation: 'Playwright', salary: '$100.10', status: , }, ]; export const Basic: Story = Template.bind({}); Basic.args = { children: defaultColumns, data: defaultData, }; export const ColumnGroups: Story = Template.bind({}); ColumnGroups.args = { density: 'extended', children: addKeys([ ID, First Last , E-Mail , Occupation , Salary , Status , ]), data: defaultData, }; export const SelectableAndNavigableRows: Story = Template.bind( {} ); SelectableAndNavigableRows.args = { density: 'extended', isSelectable: true, isActionable: true, children: addKeys([ ID , First , Last , E-Mail , Occupation , Salary , Status , ]), data: defaultData, }; export const DisabledRows: Story = Template.bind({}); DisabledRows.args = { children: defaultColumns, data: map(defaultData, (row, index) => ({ ...row, isDisabled: !!(index % 2), })), }; export const Empty: Story = Template.bind({}); Empty.args = { isFullWidth: true, density: 'extended', children: addKeys([ ID, First , Last , E-Mail , Occupation , ]), data: [], }; /* Interactive Table */ export const InteractiveTable: Story = (args) => { const Component = createReactClass({ getInitialState() { return { activeIndex: 1, currentlySortedField: 'id', currentlySortedFieldDirection: 'down', data: [ { id: '01', first_name: 'Isaac', last_name: 'Newton', email: 'inewton@example.com', occupation: 'Physicist', isSelected: true, salary: '$100.01', status: , }, { id: '02', first_name: 'Albert', last_name: 'Einstein', email: 'aeinstein@example.com', occupation: 'Physicist', salary: '$100.02', status: , }, { id: '03', first_name: (
Leon
The Silly
), last_name: 'da Vinci', email: 'ldvinci@example.com', occupation: 'Engineer', salary: '$100.03', status: , }, { id: '04', first_name: 'Aristotle', last_name: '--', email: 'aristotle@example.com', occupation: 'Tutor', salary: '$100.04', status: , }, { id: '05', first_name: 'Galileo', last_name: 'Galilei', email: 'ggalilei@example.com', occupation: 'Physicist', salary: '$100.05', status: , }, { id: '06', first_name: 'Charles', last_name: 'Darwin', email: 'cdarwin@example.com', occupation: 'Biologist', salary: '$100.06', status: , }, { id: '07', first_name: 'Alexander', last_name: 'Macedon', email: 'amacedon@example.com', occupation: 'Head of State', salary: '$100.07', status: , }, { id: '08', first_name: 'Plato', last_name: 'Plato', email: 'plato@example.com', occupation: 'Philosopher', salary: '$100.08', status: , }, { id: '09', first_name: 'Mahatma', last_name: 'Gandhi', email: 'mgandhi@example.com', occupation: 'Politician', salary: '$100.09', status: , }, { id: '10', first_name: 'William', last_name: 'Shakespeare', email: 'wshakespear@example.com', occupation: 'Playwright', salary: '$100.10', status: , }, ], }; }, handleSelect(_item: any, selectedIndex: any) { const { data } = this.state; this.setState({ data: map(data, (row, rowIndex) => { if (rowIndex === selectedIndex) { return { ...row, isSelected: !row.isSelected, }; } else { return row; } }), }); }, handleSelectAll() { const { data } = this.state; const allSelected = every(data, 'isSelected'); this.setState({ data: map(data, (row) => { return { ...row, isSelected: !allSelected, }; }), }); }, handleRowClick(_item: any, rowIndex: any) { this.setState({ activeIndex: rowIndex, }); }, handleSort(field: any) { const { currentlySortedField, currentlySortedFieldDirection, data } = this.state; const nextCurrentlySortedFieldDirection = currentlySortedField === field && currentlySortedFieldDirection === 'up' ? 'down' : 'up'; const nextData = sortBy(data, field); this.setState({ currentlySortedField: field, currentlySortedFieldDirection: nextCurrentlySortedFieldDirection, data: nextCurrentlySortedFieldDirection === 'down' ? nextData : reverse(nextData), activeIndex: null, }); }, render() { const { activeIndex, data, currentlySortedField, currentlySortedFieldDirection, } = this.state; return (
index === activeIndex ? { ...row, isActive: true } : row )} density='extended' isSelectable isActionable onRowClick={this.handleRowClick} onSelect={this.handleSelect} onSelectAll={this.handleSelectAll} onSort={this.handleSort} > ID First Last E-Mail Occupation Salary Status
); }, }); return ; }; /* Empty With Custom Title And Body */ export const EmptyWithCustomTitleAndBody: Story = (args) => { const { EmptyStateWrapper, EmptyStateWrapper: { Title, Body }, } = DataTable; const Component = createClass({ getInitialState() { return { data: [], }; }, render() { const { data } = this.state; return ( Something went wrong. Echo park poutine esse tempor squid do. Lo-fi ramps XOXO chicharrones laboris, portland fugiat locavore. Fap four dollar toast keytar, cronut kogi fingerstache distillery microdosing everyday carry austin DIY dreamcatcher. Distillery flexitarian meditation laboris roof party. Cred raclette gastropub tilde PBR&B. Shoreditch poke adipisicing, reprehenderit lumbersexual succulents mustache officia franzen vinyl nostrud af. Hashtag bitters organic, before they sold out butcher cronut sapiente. ID First Last E-Mail Occupation ); }, }); return ; }; /* Empty With Image */ export const EmptyWithImage: Story = (args) => { const { EmptyStateWrapper, EmptyStateWrapper: { Title, Body }, } = DataTable; const Component = createClass({ getInitialState() { return { data: [], }; }, render() { const { data } = this.state; return ( No items found. ID First Last E-Mail Occupation ); }, }); return ; }; /* Empty With Anchored Message */ export const EmptyWithAnchoredMessage: Story = (args) => { const Component = createClass({ getInitialState() { return { activeIndex: 1, data: [], }; }, render() { const { activeIndex, data } = this.state; return ( index === activeIndex ? { ...row, isActive: true } : row )} density='extended' isFullWidth anchorMessage minRows={15} > ID First Last E-Mail Occupation ); }, }); return ; }; /* Loading */ export const Loading: Story = (args) => { const Component = createClass({ render() { return ( ID First Last E-Mail Occupation ); }, }); return ; }; /* Loading With Anchored Message */ export const LoadingWithAnchoredMessage: Story = (args) => { const Component = createClass({ render() { return ( ID First Last E-Mail Occupation ); }, }); return ; }; /* Min Rows */ export const MinRows: Story = (args) => { const data = [ { id: 1, first_name: 'Isaac', last_name: 'Newton', email: 'inewton@example.com', occupation: 'Physicist', salary: '$100.01', status: , }, { id: 2, first_name: 'Albert', last_name: 'Einstein', email: 'aeinstein@example.com', occupation: 'Physicist', salary: '$100.02', status: , }, { id: 3, first_name: 'Leonardo', last_name: 'da Vinci', email: 'ldvinci@example.com', occupation: 'Engineer', salary: '$100.03', status: , }, { id: 4, first_name: 'Aristotle', last_name: null, email: 'aristotle@example.com', occupation: 'Tutor', salary: '$100.04', status: , }, ]; const Component = createClass({ getInitialState() { return { activeIndex: 1, data, }; }, render() { const { activeIndex, data } = this.state; return ( index === activeIndex ? { ...row, isActive: true } : row )} density='extended' isSelectable isActionable isFullWidth minRows={7} > ID First Last E-Mail Occupation Salary Status ); }, }); return ; }; /* Fixed Headers */ export const FixedHeaders: Story = () => { const data = [ { id: 1, first_name: 'Isaac', last_name: 'Newton', email: 'inewton@example.com', occupation: 'Physicist', salary: '$100.01', status: , }, { id: 2, first_name: 'Albert', last_name: 'Einstein', email: 'aeinstein@example.com', occupation: 'Physicist', salary: '$100.02', status: , isSelected: true, }, { id: 3, first_name: 'Leonardo', last_name: 'da Vinci', email: 'ldvinci@example.com', occupation: 'Engineer', salary: '$100.03', status: , isActive: true, }, { id: 4, first_name: 'Aristotle', last_name: null, email: 'aristotle@example.com', occupation: 'Tutor', salary: '$100.04', status: , }, { id: 5, first_name: 'Galileo', email: 'ggalilei@example.com', occupation: 'Physicist', salary: '$100.05', status: , }, { id: 6, first_name: 'Charles', last_name: 'Darwin', email: 'cdarwin@example.com', occupation: 'Biologist', salary: '$100.06', status: , }, { id: 7, first_name: 'Alexander', last_name: 'Macedon', email: 'amacedon@example.com', occupation: 'Head of State', salary: '$100.07', status: , }, { id: 8, first_name: 'Plato', last_name: 'Plato', email: 'plato@example.com', occupation: 'Philosopher', salary: '$100.08', status: , }, { id: 9, first_name: 'Mahatma', last_name: 'Gandhi', email: 'mgandhi@example.com', occupation: 'Politician', salary: '$100.09', status: , }, { id: 10, first_name: 'William', last_name: 'Shakespeare', email: 'wshakespear@example.com', occupation: 'Playwright', salary: '$100.10', status: , }, ]; const Component = createClass({ getInitialState() { return { hasFixedHeader: true, isSelectable: true, hasLightHeader: false, fixedColumnCount: 2, fixedRowHeight: 50, isActionable: false, }; }, handleToggle(stateItem: any) { this.setState({ [stateItem]: !this.state[stateItem] }); }, handleNumeric(stateItem: any, value: any) { this.setState({ [stateItem]: value }); }, renderDataTable(props: any) { return ( ID First Last E-Mail Occupation Salary Status ); }, render() { return (
this.handleToggle('hasFixedHeader')} /> this.handleToggle('isSelectable')} /> this.handleToggle('hasLightHeader')} /> this.handleToggle('isActionable')} />
{this.renderDataTable(this.state)}
); }, }); return ; }; /* Resizable Fixed Headers Table */ export const ResizableFixedHeadersTable: Story = () => { const data = [ { id: 1, first_name: 'Isaac', last_name: 'Newton', email: 'inewton@example.com', occupation: 'Physicist', salary: '$100.01', status: , }, { id: 2, first_name: 'Albert', last_name: 'Einstein', email: 'aeinstein@example.com', occupation: 'Physicist', salary: '$100.02', status: , isSelected: true, }, { id: 3, first_name: 'Leonardo', last_name: 'da Vinci', email: 'ldvinci@example.com', occupation: 'Engineer', salary: '$100.03', status: , isActive: true, }, { id: 4, first_name: 'Aristotle', last_name: null, email: 'aristotle@example.com', occupation: 'Tutor', salary: '$100.04', status: , }, { id: 5, first_name: 'Galileo', email: 'ggalilei@example.com', occupation: 'Physicist', salary: '$100.05', status: , }, { id: 6, first_name: 'Charles', last_name: 'Darwin', email: 'cdarwin@example.com', occupation: 'Biologist', salary: '$100.06', status: , }, { id: 7, first_name: 'Alexander', last_name: 'Macedon', email: 'amacedon@example.com', occupation: 'Head of State', salary: '$100.07', status: , }, { id: 8, first_name: 'Plato', last_name: 'Plato', email: 'plato@example.com', occupation: 'Philosopher', salary: '$100.08', status: , }, { id: 9, first_name: 'Mahatma', last_name: 'Gandhi', email: 'mgandhi@example.com', occupation: 'Politician', salary: '$100.09', status: , }, { id: 10, first_name: 'William', last_name: 'Shakespeare', email: 'wshakespear@example.com', occupation: 'Playwright', salary: '$100.10', status: , }, ]; const Component = createClass({ getInitialState() { return { hasFixedHeader: true, isSelectable: true, hasLightHeader: false, fixedColumnCount: 2, fixedRowHeight: 50, isActionable: false, }; }, handleToggle(stateItem: any) { this.setState((prevState: any) => ({ [stateItem]: !prevState[stateItem], })); }, handleNumeric(stateItem: any, value: any) { this.setState({ [stateItem]: value }); }, onChangeFixedColumnCount(prarm: any) { this.handleNumeric('fixedColumnCount', parseInt(prarm, 10)); }, onChangeFixedRowHeight(prarm: any) { this.handleNumeric('fixedRowHeight', parseInt(prarm, 10)); }, renderDataTable(props: any) { return ( ID First Last E-Mail Occupation Salary Status ); }, render() { return (
this.handleToggle('hasFixedHeader')} /> this.handleToggle('isSelectable')} /> this.handleToggle('hasLightHeader')} /> this.handleToggle('isActionable')} />
{this.renderDataTable(this.state)}
); }, }); return ; }; /* Truncate Content */ export const TruncateContent: Story = () => { const data = [ { id: 1, first_name: 'Isaac', last_name: 'Newton', email: 'inewton@example.com', occupation: 'Physicist mathematician', salary: '$100.01', status: , }, { id: 2, first_name: 'Albert', last_name: 'Einstein', email: 'aeinstein@example.com', occupation: 'Physicist', salary: '$100.02', status: , }, { id: 3, first_name: 'Leonardo', last_name: 'da Vinci', email: 'ldvinci@example.com', occupation: 'Engineer', salary: '$100.03', status: , }, { id: 4, first_name: 'Aristotle', last_name: null, email: 'aristotle@example.com', occupation: 'Tutor', salary: '$100.04', status: , }, { id: 5, first_name: 'Galileo', email: 'ggalilei@example.com', occupation: 'Physicist', salary: '$100.05', status: , }, { id: 6, first_name: 'Charles', last_name: 'Darwin', email: 'cdarwin@example.com', occupation: 'Biologist', salary: '$100.06', status: , }, { id: 7, first_name: 'Alexander', last_name: 'Macedon', email: 'amacedon@example.com', occupation: 'Head of State', salary: '$100.07', status: , }, { id: 8, first_name: 'Plato', last_name: 'Plato', email: 'plato@example.com', occupation: 'Philosopher', salary: '$100.08', status: , }, { id: 9, first_name: 'Mahatma', last_name: 'Gandhi', email: 'mgandhi@example.com', occupation: 'Politician', salary: '$100.09', status: , }, { id: 10, first_name: 'William', last_name: 'Shakespeare', email: 'wshakespear@example.com', occupation: 'Playwright', salary: '$100.10', status: , }, ]; const Component = createClass({ render() { return ( ID First Last E-Mail Long Occupation Large Salary Status ); }, }); return ; };