Skip to content

Commit

Permalink
[Table] Newly focused cell after keyboard navigation is now transform…
Browse files Browse the repository at this point in the history
…ed (#2988)

* newly focused cell after keyboard navigation is now transformed, fixes #2871

* removed unnecessary tslint directive

* selectedRegionTransform() may return a new region so forEach() is not enough

* ISelectedRegionTransform now also accepts keyboard events
  • Loading branch information
ntamas authored and giladgray committed Oct 4, 2018
1 parent 6fe1ac6 commit 9daee54
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
66 changes: 66 additions & 0 deletions packages/table-dev-app/src/mutableTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ export enum CellContent {
LARGE_JSON = "large-json",
}

export enum SelectedRegionTransformPreset {
CELL = "cell",
ROW = "row",
COLUMN = "column",
}

type IMutableStateUpdateCallback = (
stateKey: keyof IMutableTableState,
) => ((event: React.FormEvent<HTMLElement>) => void);
Expand All @@ -77,6 +83,12 @@ const REGION_CARDINALITIES: RegionCardinality[] = [

const RENDER_MODES: RenderMode[] = [RenderMode.BATCH_ON_UPDATE, RenderMode.BATCH, RenderMode.NONE];

const SELECTION_MODES: SelectedRegionTransformPreset[] = [
SelectedRegionTransformPreset.CELL,
SelectedRegionTransformPreset.ROW,
SelectedRegionTransformPreset.COLUMN,
];

const CELL_CONTENTS: CellContent[] = [
CellContent.EMPTY,
CellContent.CELL_NAMES,
Expand Down Expand Up @@ -183,6 +195,16 @@ function contains(arr: any[], value: any) {
return arr.indexOf(value) >= 0;
}

function enforceWholeColumnSelection(region: IRegion) {
delete region.rows;
return region;
}

function enforceWholeRowSelection(region: IRegion) {
delete region.cols;
return region;
}

export interface IMutableTableState {
cellContent?: CellContent;
cellTruncatedPopoverMode?: TruncatedPopoverMode;
Expand Down Expand Up @@ -214,6 +236,7 @@ export interface IMutableTableState {
scrollToRegionType?: RegionCardinality;
scrollToRowIndex?: number;
selectedFocusStyle?: FocusStyle;
selectedRegionTransformPreset?: SelectedRegionTransformPreset;
showCallbackLogs?: boolean;
showCellsLoading?: boolean;
showColumnHeadersLoading?: boolean;
Expand Down Expand Up @@ -259,6 +282,7 @@ const DEFAULT_STATE: IMutableTableState = {
scrollToRegionType: RegionCardinality.CELLS,
scrollToRowIndex: 0,
selectedFocusStyle: FocusStyle.TAB,
selectedRegionTransformPreset: SelectedRegionTransformPreset.CELL,
showCallbackLogs: true,
showCellsLoading: false,
showColumnHeadersLoading: false,
Expand Down Expand Up @@ -377,6 +401,7 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
ref={this.refHandlers.table}
renderMode={this.state.renderMode}
rowHeaderCellRenderer={this.renderRowHeader}
selectedRegionTransform={this.getSelectedRegionTransform()}
selectionModes={this.getEnabledSelectionModes()}
styledRegionGroups={this.getStyledRegionGroups()}
>
Expand Down Expand Up @@ -577,6 +602,13 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
this.toRenderModeLabel,
this.handleNumberStateChange,
);
const selectedRegionTransformPresetMenu = this.renderSelectMenu(
"Selection",
"selectedRegionTransformPreset",
SELECTION_MODES,
this.toSelectedRegionTransformPresetLabel,
this.handleSelectedRegionTransformPresetChange,
);
const cellContentMenu = this.renderSelectMenu(
"Cell content",
"cellContent",
Expand Down Expand Up @@ -617,6 +649,7 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
{this.renderSwitch("Callback logs", "showCallbackLogs")}
{this.renderSwitch("Full-table selection", "enableFullTableSelection")}
{this.renderSwitch("Multi-selection", "enableMultiSelection")}
{selectedRegionTransformPresetMenu}
<H6>Scroll to</H6>
{this.renderScrollToSection()}

Expand Down Expand Up @@ -855,6 +888,19 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
}
}

private toSelectedRegionTransformPresetLabel(selectedRegionTransformPreset: SelectedRegionTransformPreset) {
switch (selectedRegionTransformPreset) {
case SelectedRegionTransformPreset.CELL:
return "Unconstrained";
case SelectedRegionTransformPreset.ROW:
return "Whole rows only";
case SelectedRegionTransformPreset.COLUMN:
return "Whole columns only";
default:
return "None";
}
}

private toCellContentLabel(cellContent: CellContent) {
switch (cellContent) {
case CellContent.CELL_NAMES:
Expand Down Expand Up @@ -1043,6 +1089,10 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
return handleNumberChange(value => this.setState({ [stateKey]: value }));
};

private handleSelectedRegionTransformPresetChange = (stateKey: keyof IMutableTableState) => {
return handleStringChange(value => this.setState({ [stateKey]: value }));
};

private updateFocusStyleState = () => {
return handleStringChange((value: string) => {
const selectedFocusStyle = value === "tab" ? FocusStyle.TAB : FocusStyle.TAB_OR_CLICK;
Expand Down Expand Up @@ -1095,6 +1145,22 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
return loadingOptions;
}

private getSelectedRegionTransform() {
switch (this.state.selectedRegionTransformPreset) {
case SelectedRegionTransformPreset.CELL:
return undefined;

case SelectedRegionTransformPreset.ROW:
return enforceWholeRowSelection;

case SelectedRegionTransformPreset.COLUMN:
return enforceWholeColumnSelection;

default:
return undefined;
}
}

private getStyledRegionGroups() {
// show 3 styled regions as samples
return !this.state.showCustomRegions
Expand Down
6 changes: 5 additions & 1 deletion packages/table/src/interactions/selectable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import { IRegion, Regions } from "../regions";
import { DragEvents } from "./dragEvents";
import { Draggable, ICoordinateData, IDraggableProps } from "./draggable";

export type ISelectedRegionTransform = (region: IRegion, event: MouseEvent, coords?: ICoordinateData) => IRegion;
export type ISelectedRegionTransform = (
region: IRegion,
event: MouseEvent | KeyboardEvent,
coords?: ICoordinateData,
) => IRegion;

export interface ISelectableProps {
/**
Expand Down
7 changes: 6 additions & 1 deletion packages/table/src/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1826,7 +1826,12 @@ export class Table extends AbstractComponent<ITableProps, ITableState> {

// change selection to match new focus cell location
const newSelectionRegions = [Regions.cell(newFocusedCell.row, newFocusedCell.col)];
this.handleSelection(newSelectionRegions);
const { selectedRegionTransform } = this.props;
const transformedSelectionRegions =
selectedRegionTransform != null
? newSelectionRegions.map(region => selectedRegionTransform(region, e))
: newSelectionRegions;
this.handleSelection(transformedSelectionRegions);
this.handleFocus(newFocusedCell);

// keep the focused cell in view
Expand Down

1 comment on commit 9daee54

@blueprint-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Table] Newly focused cell after keyboard navigation is now transformed (#2988)

Previews: documentation | landing | table

Please sign in to comment.