Skip to content
Open
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
File renamed without changes.
24 changes: 24 additions & 0 deletions src/components/table/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import classNames from 'classnames';

export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
/** Contents of the table */
children: React.ReactNode;
/** Additional CSS class for the table */
className?: string;
/** Whether to render the table in compact mode */
isCompact?: boolean;
}

const Table = ({ children, className = '', isCompact = false, ...rest }: TableProps) => (
<table
className={classNames('table', className, {
'is-compact': isCompact,
})}
{...rest}
>
{children}
</table>
);

export default Table;
15 changes: 15 additions & 0 deletions src/components/table/TableBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import classNames from 'classnames';

export interface TableBodyProps {
/** Body rows of the table */
children: React.ReactNode;
/** Additional CSS class for the table body */
className?: string;
}

const TableBody = ({ children, className = '' }: TableBodyProps) => (
<tbody className={classNames('table-body', className)}>{children}</tbody>
);

export default TableBody;
24 changes: 24 additions & 0 deletions src/components/table/TableCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import classNames from 'classnames';

export interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
/** Contents of the table cell */
children: React.ReactNode;
/** Additional CSS class for the cell */
className?: string;
/** Whether the cell has a fixed width */
isFixedWidth?: boolean;
}

const TableCell = ({ children, className = '', isFixedWidth = false, ...rest }: TableCellProps) => (
<td
className={classNames('table-cell', className, {
'is-fixed-width': isFixedWidth,
})}
{...rest}
>
{children}
</td>
);

export default TableCell;
21 changes: 21 additions & 0 deletions src/components/table/TableHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react';
import classNames from 'classnames';

import TableRow from './TableRow';

export interface TableHeaderProps {
/** Header cells of the table */
children: React.ReactNode;
/** Additional CSS class for the table header */
className?: string;
/** Additional CSS class for the header row */
rowClassName?: string;
}

const TableHeader = ({ children, className = '', rowClassName = '' }: TableHeaderProps) => (
<thead className={classNames('table-header', className)}>
<TableRow className={rowClassName}>{children}</TableRow>
</thead>
);

export default TableHeader;
24 changes: 24 additions & 0 deletions src/components/table/TableHeaderCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import classNames from 'classnames';

export interface TableHeaderCellProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
/** Contents of the header cell */
children?: React.ReactNode;
/** Additional CSS class for the header cell */
className?: string;
/** Whether the header cell has a fixed width */
isFixedWidth?: boolean;
}

const TableHeaderCell = ({ children, className = '', isFixedWidth = false, ...rest }: TableHeaderCellProps) => (
<th
className={classNames('table-cell', className, {
'is-fixed-width': isFixedWidth,
})}
{...rest}
>
{children}
</th>
);

export default TableHeaderCell;
19 changes: 19 additions & 0 deletions src/components/table/TableRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import classNames from 'classnames';

export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
/** Cells of the table row */
children: React.ReactNode;
/** Additional CSS class for the row */
className?: string;
/** Ref for the table row element */
rowRef?: React.Ref<HTMLTableRowElement>;
}

const TableRow = ({ children, className = '', rowRef, ...rest }: TableRowProps) => (
<tr ref={rowRef} className={classNames('table-row', className)} {...rest}>
{children}
</tr>
);

export default TableRow;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';

import Table from '../Table';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';

import TableBody from '../TableBody';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';

import TableCell from '../TableCell';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';

import TableHeader from '../TableHeader';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';

import TableHeaderCell from '../TableHeaderCell';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { shallow } from 'enzyme';

import TableRow from '../TableRow';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// @ts-nocheck Enzyme instance() is untyped for this HOC class component
import * as React from 'react';
import { Set } from 'immutable';
import sinon from 'sinon';
import { shallow } from 'enzyme';

import isEqual from 'lodash/isEqual';

Expand Down Expand Up @@ -35,7 +37,7 @@ describe('components/table/makeSelectable', () => {
const instance = wrapper.instance();
const shortcut = instance.getHotkeyConfigs().find(h => h.get('key') === hotKey);
shortcut.handler({ preventDefault: sandbox.stub() });
expect(wrapper.state('focusedIndex')).toEqual(undefined);
expect(wrapper.state('focusedIndex')).toBeUndefined();
};

afterEach(() => {
Expand Down Expand Up @@ -750,7 +752,7 @@ describe('components/table/makeSelectable', () => {
const instance = wrapper.instance();
const shortcut = instance.getHotkeyConfigs().find(h => h.get('key') === hotKey);
shortcut.handler({ preventDefault: sandbox.stub() });
expect(wrapper.state('focusedIndex')).toEqual(undefined);
expect(wrapper.state('focusedIndex')).toBeUndefined();
});
});

Expand Down Expand Up @@ -956,7 +958,7 @@ describe('components/table/makeSelectable', () => {
const instance = wrapper.instance();
const shortcut = instance.getHotkeyConfigs().find(h => h.get('key') === hotKey);
shortcut.handler({ target: { role: 'slider' } });
expect(wrapper.state('focusedIndex')).toEqual(undefined);
expect(wrapper.state('focusedIndex')).toBeUndefined();
});

test('should call event.preventDefault() and set focus to next item', () => {
Expand Down Expand Up @@ -1006,7 +1008,7 @@ describe('components/table/makeSelectable', () => {
const instance = wrapper.instance();
const shortcut = instance.getHotkeyConfigs().find(h => h.get('key') === hotKey);
shortcut.handler({ target: { role: 'slider' } });
expect(wrapper.state('focusedIndex')).toEqual(undefined);
expect(wrapper.state('focusedIndex')).toBeUndefined();
});

test('should call event.preventDefault() and call onSelect with new focused item', () => {
Expand Down Expand Up @@ -1081,7 +1083,7 @@ describe('components/table/makeSelectable', () => {
const instance = wrapper.instance();
const shortcut = instance.getHotkeyConfigs().find(h => h.get('key') === hotKey);
shortcut.handler({ target: { role: 'slider' } });
expect(wrapper.state('focusedIndex')).toEqual(undefined);
expect(wrapper.state('focusedIndex')).toBeUndefined();
});

test('should call event.preventDefault() and set focus to next row item', () => {
Expand Down Expand Up @@ -1131,7 +1133,7 @@ describe('components/table/makeSelectable', () => {
const instance = wrapper.instance();
const shortcut = instance.getHotkeyConfigs().find(h => h.get('key') === hotKey);
shortcut.handler({ target: { role: 'slider' } });
expect(wrapper.state('focusedIndex')).toEqual(undefined);
expect(wrapper.state('focusedIndex')).toBeUndefined();
});

test('should call event.preventDefault() and call onSelect with new focused item', () => {
Expand Down
36 changes: 0 additions & 36 deletions src/components/table/__tests__/shiftSelect.test.js

This file was deleted.

38 changes: 38 additions & 0 deletions src/components/table/__tests__/shiftSelect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Set } from 'immutable';

import shiftSelect from '../shiftSelect';

describe('components/table/shiftSelect', () => {
(
[
// prevSelection, prevTarget, target, anchor, expected
// [PrevTarget, Anchor, Target]
[[1, 2], 0, 3, 1, [1, 2, 3]],
[[0], 0, 2, 1, [1, 2]],
// [PrevTarget, Target, Anchor]
[[3, 4], 0, 1, 2, [1, 2, 3, 4]],
[[0], 0, 1, 2, [1, 2]],
// [Anchor, PrevTarget, Target]
[[0, 1, 9], 1, 2, 0, [0, 1, 2, 9]],
// [Anchor, Target, PrevTarget]
[[0, 1, 2, 3, 4, 9], 4, 2, 0, [0, 1, 2, 9]],
// [Target, Anchor, PrevTarget]
[[0, 1, 2, 3, 4, 9], 4, 0, 2, [0, 1, 2, 9]],
// [Target, PrevTarget, Anchor]
[[2, 3, 4, 9], 2, 0, 4, [0, 1, 2, 3, 4, 9]],
] as Array<[number[], number, number, number, number[]]>
).forEach(([prevSelection, prevTarget, target, anchor, expected], index) => {
const expectedSet = Set(expected);
test(`should select the correct elements (data set #${index})`, () => {
const ret = shiftSelect(Set(prevSelection), prevTarget, target, anchor);
expect(ret.equals(expectedSet)).toBeTruthy();
});
});

test('should throw when params are invalid (very rare)', () => {
const prevSelection = Set([1, 2, 3, 4]);
expect(() => {
shiftSelect(prevSelection, undefined, undefined, undefined);
}).toThrow();
});
});
File renamed without changes.
14 changes: 14 additions & 0 deletions src/components/table/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export { default as Table } from './Table';
export { default as TableBody } from './TableBody';
export { default as TableCell } from './TableCell';
export { default as TableHeader } from './TableHeader';
export { default as TableHeaderCell } from './TableHeaderCell';
export { default as TableRow } from './TableRow';
export { default as makeSelectable } from './makeSelectable';
export type { TableProps } from './Table';
export type { TableBodyProps } from './TableBody';
export type { TableCellProps } from './TableCell';
export type { TableHeaderProps } from './TableHeader';
export type { TableHeaderCellProps } from './TableHeaderCell';
export type { TableRowProps } from './TableRow';
export type { MakeSelectableProps } from './makeSelectable';
Loading
Loading