Skip to content

Commit

Permalink
[Table] Add docs about reorderable content (#1271)
Browse files Browse the repository at this point in the history
* Add Utils.some

* [Temporary] Change feature flags in Table example

* Add new classes for reorder handle

* Add ignoredSelector prop to DragSelectable

* Add preliminary styles for reorder handle

* Add reorder handle to column interaction bar

* Ignore reorder handle selector

* Reorder handle works

* Renable drag-reordering on rows

* Delete commented code

* Show column grab cursor only over reorder handle

* Move selection only if it existed before reorder

* Don't disable drage selection for column headers

* Different handle colors on :hover and :active

* Delete console.logs

* Select clicked handle's column if not selected

* Reenable old reordering interaction if useInteractionBar={false}

* Delete reorderHandle.tsx, put Orientation back in resizeHandle.tsx

* Code cleanups

* Rename to isEntireCellTargetReorderable

* Delete orientation.ts

* Have Header apply the TABLE_HEADER_REORDERABLE class

* Reply to CR feedback

* Fix tests

* Write new tests, fix bug

* Add deprecation warning to HeaderCell#isReorderable

* Fix lint

* Fix deprecation version

* Fix deprecation message

* Add reorderable example to site-docs
  • Loading branch information
cmslewis committed Jun 22, 2017
1 parent ff341f4 commit b607b5d
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/table/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export * from "./tableDollarExample";
export * from "./tableEditableExample";
export * from "./tableFormatsExample";
export * from "./tableLoadingExample";
export * from "./tableReorderableExample";
export * from "./tableSortableExample";
106 changes: 106 additions & 0 deletions packages/table/examples/tableReorderableExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2017 Palantir Technologies, Inc. All rights reserved.
* Licensed under the BSD-3 License as modified (the “License”); you may obtain a copy
* of the license at https://github.com/palantir/blueprint/blob/master/LICENSE
* and https://github.com/palantir/blueprint/blob/master/PATENTS
*/

import * as React from "react";

import { Switch } from "@blueprintjs/core";
import { BaseExample, handleBooleanChange } from "@blueprintjs/docs";

import {
Cell,
Column,
Table,
Utils,
} from "../src";

export interface ITableReorderableExampleState {
columns?: JSX.Element[];
data?: any[];
useInteractionBar?: boolean;
}

const REORDERABLE_TABLE_DATA = [
["A", "Apple", "Ape", "Albania", "Anchorage"],
["B", "Banana", "Boa", "Brazil", "Boston"],
["C", "Cranberry", "Cougar", "Croatia", "Chicago"],
["D", "Dragonfruit", "Deer", "Denmark", "Denver"],
["E", "Eggplant", "Elk", "Eritrea", "El Paso"],
].map(([letter, fruit, animal, country, city]) => ({ letter, fruit, animal, country, city }));

export class TableReorderableExample extends BaseExample<ITableReorderableExampleState> {
public state: ITableReorderableExampleState = {
data: REORDERABLE_TABLE_DATA,
useInteractionBar: false,
};

private toggleUseInteractionBar = handleBooleanChange((useInteractionBar) => this.setState({ useInteractionBar }));

public componentDidMount() {
const { useInteractionBar } = this.state;
const columns = [
<Column key="1" name="Letter" renderCell={this.renderLetterCell} useInteractionBar={useInteractionBar} />,
<Column key="2" name="Fruit" renderCell={this.renderFruitCell} useInteractionBar={useInteractionBar} />,
<Column key="3" name="Animal" renderCell={this.renderAnimalCell} useInteractionBar={useInteractionBar} />,
<Column key="4" name="Country" renderCell={this.renderCountryCell} useInteractionBar={useInteractionBar} />,
<Column key="5" name="City" renderCell={this.renderCityCell} useInteractionBar={useInteractionBar} />,
];
this.setState({ columns });
}

public componentDidUpdate(_nextProps: {}, nextState: ITableReorderableExampleState) {
const { useInteractionBar } = this.state;
if (nextState.useInteractionBar !== useInteractionBar) {
const nextColumns = React.Children.map(this.state.columns, (column: JSX.Element) => {
return React.cloneElement(column, { useInteractionBar });
});
this.setState({ columns: nextColumns });
}
}

public renderExample() {
return (
<Table
isColumnReorderable={true}
isColumnResizable={false}
isRowReorderable={true}
isRowResizable={false}
numRows={this.state.data.length}
onColumnsReordered={this.handleColumnsReordered}
onRowsReordered={this.handleRowsReordered}
>
{this.state.columns}
</Table>
);
}

protected renderOptions() {
return (
<Switch
checked={this.state.useInteractionBar}
label="Interaction bar"
onChange={this.toggleUseInteractionBar}
/>
);
}

private renderLetterCell = (row: number) => <Cell>{this.state.data[row].letter}</Cell>;
private renderFruitCell = (row: number) => <Cell>{this.state.data[row].fruit}</Cell>;
private renderAnimalCell = (row: number) => <Cell>{this.state.data[row].animal}</Cell>;
private renderCountryCell = (row: number) => <Cell>{this.state.data[row].country}</Cell>;
private renderCityCell = (row: number) => <Cell>{this.state.data[row].city}</Cell>;

private handleColumnsReordered = (oldIndex: number, newIndex: number, length: number) => {
if (oldIndex === newIndex) { return; }
const nextChildren = Utils.reorderArray(this.state.columns, oldIndex, newIndex, length);
this.setState({ columns: nextChildren });
}

private handleRowsReordered = (oldIndex: number, newIndex: number, length: number) => {
if (oldIndex === newIndex) { return; }
this.setState({ data: Utils.reorderArray(this.state.data, oldIndex, newIndex, length) });
}
}
20 changes: 20 additions & 0 deletions packages/table/src/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@ regular expression (`[a-zA-Z]`). If the content is invalid, a

@reactExample TableEditableExample

@## Reorderable content

The table supports column and row reordering via the `isColumnReorderable` and `isRowReorderable`
props, respectively. The table also requires the `FULL_COLUMNS` selection mode to be enabled for
column reordering and the `FULL_ROWS` selection mode to be enabled for row reordering; these can be
set via the `selectionModes` prop.

To reorder a single row or column, first click its header cell to select it, then click and drag the
header cell again to move it elsewhere. Likewise, to reorder multiple consecutive rows or columns at
once, click and drag across multiple header cells to select the range, then click and drag anywhere in
the selected header cells to move them as a group.

<div class="pt-callout pt-intent-primary pt-icon-info-sign">
<h5>Column reordering with interaction bar enabled</h5>
When the interaction bar is enabled, the table will show handle icons in the interaction bar that
you can drag directly without having to make a selection first.
</div>

@reactExample TableReorderableExample

@## Loading states

When fetching or updating data, it may be desirable to show a loading state. The table components
Expand Down

0 comments on commit b607b5d

Please sign in to comment.