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

[table] feat(Table2): new 'scroll' instance method #5968

Merged
merged 39 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
42a13f8
added 'scroll' function to table2 properties to enable outside scroll…
ccullotta Feb 23, 2023
3851cd5
lint fix, also added some basic doc strings
ccullotta Feb 23, 2023
a0b3c8e
ran prettier
ccullotta Feb 23, 2023
2b59f6a
created basic demo
ccullotta Feb 23, 2023
08c65cd
making demo a little nicer
ccullotta Feb 24, 2023
a1fe04f
Merge remote-tracking branch 'origin/develop' into cc/enable-scroll-c…
adidahiya Feb 27, 2023
53978a1
annotate type exports to avoid webpack warnings
adidahiya Feb 27, 2023
51feb44
remove unnecessary copyright
adidahiya Feb 27, 2023
4b092db
fixed auto scrolling behavior
ccullotta Feb 28, 2023
9c2ae65
Update packages/table/src/table2.tsx
ccullotta Feb 28, 2023
60a85d3
merge in suggested parameter fix to enforce some consistency
ccullotta Feb 28, 2023
954bcbb
fixed small scroll bug
ccullotta Feb 28, 2023
cf141e9
add cursor scroll indicator
ccullotta Mar 1, 2023
ce6e753
got linear gradient working
ccullotta Mar 1, 2023
37b0485
small fixes
ccullotta Mar 1, 2023
3ddfc59
removed cruft and will-change edits
ccullotta Mar 1, 2023
322acd0
reformatted setScrollOverlayBackground to be more customizable
ccullotta Mar 1, 2023
de1a807
added fade in, and removed fade at top and bottom
ccullotta Mar 1, 2023
2f52c08
added fade-out animation
ccullotta Mar 2, 2023
4ba4dbf
added back scroll at top behavior
ccullotta Mar 2, 2023
b248422
fixed some docstrings and cruft
ccullotta Mar 2, 2023
a30e41f
fixed lint issues
ccullotta Mar 2, 2023
5b05222
merged scroll and setScrolling indicator into setScrolling
ccullotta Mar 2, 2023
f3d5c45
Update packages/table/src/table2.tsx
ccullotta Mar 2, 2023
ff8bf12
Update packages/table/src/table2.tsx
ccullotta Mar 2, 2023
5dda1fe
Update packages/table/src/table2.tsx
ccullotta Mar 2, 2023
9e0506e
updated names, small refactors, improved scroll indicator to go away …
ccullotta Mar 2, 2023
db261b0
merged into table demo
ccullotta Mar 2, 2023
d4e7204
adding enum that was accidentally ommitted
ccullotta Mar 2, 2023
4cbe6de
adding function to base table, and adding documentation to blueprint …
ccullotta Mar 3, 2023
ab62c1e
removing cruft
ccullotta Mar 3, 2023
9ae3e12
removing inline style cruft in mutable table
ccullotta Mar 3, 2023
5a278e5
removing styles we didnt need, making the reduced height only apply w…
ccullotta Mar 3, 2023
8b06ab0
fixed bug causing inline switch to not work as intended
ccullotta Mar 3, 2023
d7f9a6b
removing cruft
ccullotta Mar 3, 2023
680a1a7
removing more cruft
ccullotta Mar 3, 2023
2109ed7
making certain state properties private class properties
ccullotta Mar 3, 2023
fd8f946
remove table update
ccullotta Mar 6, 2023
17f4295
use table2 for documentation string
ccullotta Mar 6, 2023
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
69 changes: 67 additions & 2 deletions packages/table-dev-app/src/mutableTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export interface IMutableTableState {
enableRowResizing?: boolean;
enableRowSelection?: boolean;
enableSlowLayout?: boolean;
enableScrollingApi?: boolean;
numCols?: number;
numFrozenCols?: number;
numFrozenRows?: number;
Expand Down Expand Up @@ -290,6 +291,7 @@ const DEFAULT_STATE: IMutableTableState = {
enableRowReordering: false,
enableRowResizing: false,
enableRowSelection: true,
enableScrollingApi: false,
enableSlowLayout: false,
numCols: COLUMN_COUNTS[COLUMN_COUNT_DEFAULT_INDEX],
numFrozenCols: FROZEN_COLUMN_COUNTS[FROZEN_COLUMN_COUNT_DEFAULT_INDEX],
Expand Down Expand Up @@ -321,10 +323,19 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {

private tableInstance: Table2;

private tableWrapperRef: HTMLDivElement;

private stateStore: LocalStore<IMutableTableState>;

private scrollDirection: "UP" | "DOWN";

private animationRequestId: number;

private previousTime: number;

private refHandlers = {
table: (ref: Table2) => (this.tableInstance = ref),
tableWrapperRef: (ref: HTMLDivElement) => (this.tableWrapperRef = ref),
};

// eslint-disable-next-line @typescript-eslint/ban-types
Expand All @@ -348,8 +359,13 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
rootClassName={classNames("table", { "is-inline": this.state.showInline })}
branchClassName="layout-passthrough-fill"
>
<div className={layoutBoundary ? "layout-boundary" : "layout-passthrough-fill"}>
{this.renderTable()}
<div
className={layoutBoundary ? "layout-boundary" : "layout-passthrough-fill"}
ref={this.refHandlers.tableWrapperRef}
onMouseOver={event => this.checkScrolling(event)}
onMouseLeave={this.cancelAnimation}
>
{this.renderTable()};
</div>
</SlowLayoutStack>
{this.renderSidebar()}
Expand Down Expand Up @@ -390,6 +406,54 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
return Math.random().toString(36).substring(7);
};

private animate = (time: number) => {
this.previousTime = this.previousTime ?? time;
if (this.tableInstance) {
const deltaTime = time - this.previousTime;
if (deltaTime > 100) {
if (this.scrollDirection === "UP") {
this.tableInstance.scrollByOffset({ left: 0, top: -10 });
} else {
this.tableInstance.scrollByOffset({ left: 0, top: +10 });
}
this.previousTime = (this.previousTime ?? 0) + 100;
}
}
this.animationRequestId = requestAnimationFrame(this.animate);
};

private cancelAnimation = () => {
cancelAnimationFrame(this.animationRequestId);
this.animationRequestId = undefined;
this.previousTime = undefined;
this.tableInstance.scrollByOffset(null);
};

private checkScrolling = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (!this.state.enableScrollingApi) {
return;
}
const top = this.tableWrapperRef.getBoundingClientRect().top;
const bottom = this.tableWrapperRef.getBoundingClientRect().bottom;
const scrollAbove = top + 0.3 * (bottom - top);
const scrollBelow = bottom - 0.3 * (bottom - top);
const pos = event.clientY;

if (pos < scrollAbove && pos > top) {
this.scrollDirection = "UP";
if (this.animationRequestId === undefined) {
requestAnimationFrame(this.animate);
}
} else if (pos > scrollBelow && pos < bottom) {
this.scrollDirection = "DOWN";
if (this.animationRequestId === undefined) {
requestAnimationFrame(this.animate);
}
} else {
this.cancelAnimation();
}
};

// Renderers
// =========

Expand Down Expand Up @@ -683,6 +747,7 @@ export class MutableTable extends React.Component<{}, IMutableTableState> {
{this.renderSwitch("Callback logs", "showCallbackLogs")}
{this.renderSwitch("Full-table selection", "enableFullTableSelection")}
{this.renderSwitch("Multi-selection", "enableMultiSelection")}
{this.renderSwitch("Demo programmatic scrolling API", "enableScrollingApi")}
{selectedRegionTransformPresetMenu}
<H6>Scroll to</H6>
{this.renderScrollToSection()}
Expand Down
5 changes: 5 additions & 0 deletions packages/table/src/common/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ const NS = Classes.getClassNamespace();

export const TABLE_BODY = `${NS}-table-body`;
export const TABLE_BODY_CELLS = `${NS}-table-body-cells`;
export const TABLE_BODY_SCROLLING_INDICATOR_OVERLAY = `${NS}-table-body-scrolling-indicator-overlay`;
export const TABLE_BODY_IS_SCROLLING_TOP = `${NS}-table-body-is-scrolling-top`;
export const TABLE_BODY_IS_SCROLLING_BOTTOM = `${NS}-table-body-is-scrolling-bottom`;
export const TABLE_BODY_IS_SCROLLING_RIGHT = `${NS}-table-body-is-scrolling-right`;
export const TABLE_BODY_IS_SCROLLING_LEFT = `${NS}-table-body-is-scrolling-left`;
export const TABLE_BODY_SCROLL_CLIENT = `${NS}-table-body-scroll-client`;
export const TABLE_BODY_VIRTUAL_CLIENT = `${NS}-table-body-virtual-client`;
export const TABLE_BOTTOM_CONTAINER = `${NS}-table-bottom-container`;
Expand Down
2 changes: 1 addition & 1 deletion packages/table/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
export type { CellCoordinates, FocusedCellCoordinates } from "./cellTypes";
export { Clipboard } from "./clipboard";
export { Grid } from "./grid";
export { Rect, AnyRect } from "./rect";
export { Rect, type AnyRect } from "./rect";
export { RenderMode } from "./renderMode";
export { Utils } from "./utils";

Expand Down
22 changes: 22 additions & 0 deletions packages/table/src/common/scrollDirection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* !
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export enum ScrollDirection {
TOP = "top",
BOTTOM = "bottom",
RIGHT = "right",
LEFT = "left",
NONE = "none",
}
2 changes: 2 additions & 0 deletions packages/table/src/docs/table-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ type ICellMapper<T> = (rowIndex: number, columnIndex: number) => T;

@method Table.scrollToRegion

@method Table2.scrollByOffset

@## Column

`Column` contains props for defining how the header and cells of that column
Expand Down
74 changes: 42 additions & 32 deletions packages/table/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,41 @@

/* eslint-disable deprecation/deprecation */

export { Cell, CellProps, ICellProps, ICellRenderer, CellRenderer } from "./cell/cell";
export { Cell, type CellProps, type ICellProps, type ICellRenderer, type CellRenderer } from "./cell/cell";
ccullotta marked this conversation as resolved.
Show resolved Hide resolved

export { EditableCell, IEditableCellProps, EditableCellProps } from "./cell/editableCell";
export { EditableCell, type IEditableCellProps, type EditableCellProps } from "./cell/editableCell";

export { EditableCell2, EditableCell2Props } from "./cell/editableCell2";
export { EditableCell2, type EditableCell2Props } from "./cell/editableCell2";

export { JSONFormat, IJSONFormatProps, JSONFormatProps } from "./cell/formats/jsonFormat";
export { JSONFormat, type IJSONFormatProps, type JSONFormatProps } from "./cell/formats/jsonFormat";

export { JSONFormat2 } from "./cell/formats/jsonFormat2";

export {
TruncatedPopoverMode,
TruncatedFormat,
TruncatedFormatProps,
ITruncatedFormatProps,
TruncatedPopoverMode,
type TruncatedFormatProps,
type ITruncatedFormatProps,
} from "./cell/formats/truncatedFormat";

export { TruncatedFormat2 } from "./cell/formats/truncatedFormat2";

export { Column, ColumnProps, IColumnProps } from "./column";
export { Column, type ColumnProps, type IColumnProps } from "./column";

export {
AnyRect,
CellCoordinates,
type AnyRect,
type CellCoordinates,
Clipboard,
FocusedCellCoordinates,
type FocusedCellCoordinates,
Grid,
Rect,
RenderMode,
Utils,
} from "./common/index";

export { IDraggableProps, Draggable } from "./interactions/draggable";
export { type IDraggableProps, Draggable } from "./interactions/draggable";

export {
export type {
IClientCoordinates,
ClientCoordinates,
ICoordinateData,
Expand All @@ -59,49 +59,59 @@ export {
DragHandler,
} from "./interactions/dragTypes";

export { CopyCellsMenuItem, IContextMenuRenderer, ContextMenuRenderer, IMenuContext } from "./interactions/menus";
export {
CopyCellsMenuItem,
type IContextMenuRenderer,
type ContextMenuRenderer,
type IMenuContext,
} from "./interactions/menus";

export { ILockableLayout, IResizeHandleProps, Orientation, ResizeHandle } from "./interactions/resizeHandle";
export {
type ILockableLayout,
type IResizeHandleProps,
type Orientation,
ResizeHandle,
} from "./interactions/resizeHandle";

export { ISelectableProps, IDragSelectableProps, DragSelectable } from "./interactions/selectable";
export { type ISelectableProps, type IDragSelectableProps, DragSelectable } from "./interactions/selectable";

export { ColumnHeaderRenderer, IColumnHeaderRenderer } from "./headers/columnHeader";
export type { ColumnHeaderRenderer, IColumnHeaderRenderer } from "./headers/columnHeader";

export { RowHeaderRenderer } from "./headers/rowHeader";
export type { RowHeaderRenderer } from "./headers/rowHeader";

export {
ColumnHeaderCell,
ColumnHeaderCellProps,
IColumnHeaderCellProps,
type ColumnHeaderCellProps,
type IColumnHeaderCellProps,
HorizontalCellDivider,
} from "./headers/columnHeaderCell";

export { ColumnHeaderCell2, ColumnHeaderCell2Props } from "./headers/columnHeaderCell2";
export { ColumnHeaderCell2, type ColumnHeaderCell2Props } from "./headers/columnHeaderCell2";

export { IRowHeaderCellProps, RowHeaderCellProps, RowHeaderCell } from "./headers/rowHeaderCell";
export { type IRowHeaderCellProps, type RowHeaderCellProps, RowHeaderCell } from "./headers/rowHeaderCell";

export { RowHeaderCell2 } from "./headers/rowHeaderCell2";

export { IEditableNameProps, EditableNameProps, EditableName } from "./headers/editableName";
export { type IEditableNameProps, type EditableNameProps, EditableName } from "./headers/editableName";

export {
CellInterval,
CellCoordinate,
type CellInterval,
type CellCoordinate,
ColumnLoadingOption,
ICellInterval,
IRegion,
Region,
IStyledRegionGroup,
type ICellInterval,
type IRegion,
type Region,
type IStyledRegionGroup,
RegionCardinality,
Regions,
RowLoadingOption,
SelectionModes,
StyledRegionGroup,
type StyledRegionGroup,
TableLoadingOption,
} from "./regions";

export { ITableProps, TableProps } from "./tableProps";
export type { ITableProps, TableProps } from "./tableProps";

export { Table } from "./table";

export { Table2, Table2Props } from "./table2";
export { Table2, type Table2Props } from "./table2";
35 changes: 35 additions & 0 deletions packages/table/src/quadrants/_quadrants.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,41 @@ $table-quadrant-scroll-container-overflow: 20px;
}
}

.#{$ns}-table-body-scrolling-indicator-overlay {
bottom: 0;
left: 0;
pointer-events: none;
position: absolute;
right: 0;
top: 0;
z-index: 1;
}

%table-is-scrolling {
opacity: 1;
transition: opacity 0.2s linear;
}

.#{$ns}-table-body-is-scrolling-top {
@extend %table-is-scrolling;
background: linear-gradient(180deg, rgba(0, 0, 0, 15%) 0%, transparent 10%);
}

.#{$ns}-table-body-is-scrolling-right {
@extend %table-is-scrolling;
background: linear-gradient(270deg, rgba(0, 0, 0, 15%) 0%, transparent 10%);
}

.#{$ns}-table-body-is-scrolling-bottom {
@extend %table-is-scrolling;
background: linear-gradient(0deg, rgba(0, 0, 0, 15%) 0%, transparent 10%);
}

.#{$ns}-table-body-is-scrolling-left {
@extend %table-is-scrolling;
background: linear-gradient(90deg, rgba(0, 0, 0, 15%) 0%, transparent 10%);
}

.#{$ns}-table-quadrant-body-container {
position: relative;
}
Expand Down
13 changes: 13 additions & 0 deletions packages/table/src/quadrants/tableQuadrantStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ export interface ITableQuadrantStackProps extends Props {
showFrozenRowsOnly?: boolean,
) => JSX.Element | undefined;

renderScrollIndicatorOverlay?: (scrollBarWidth: number, columnHeaderHeight: number) => JSX.Element | undefined;

/**
* A callback that receives a `ref` to the main quadrant's row-header container.
*/
Expand Down Expand Up @@ -435,6 +437,7 @@ export class TableQuadrantStack extends AbstractComponent2<ITableQuadrantStackPr

return (
<div className={Classes.TABLE_QUADRANT_STACK}>
{this.renderTableOverlay()}
<TableQuadrant
{...baseProps}
bodyRef={this.props.bodyRef}
Expand Down Expand Up @@ -479,6 +482,16 @@ export class TableQuadrantStack extends AbstractComponent2<ITableQuadrantStackPr
return refHandlers.reduce(reducer, {});
}

// Scrolling overlay renderer
// ===========================

private renderTableOverlay = () => {
const columnHeaderHeight = this.cache.getColumnHeaderHeight();
const mainScrollContainer = this.quadrantRefs[QuadrantType.MAIN].scrollContainer;
const scrollBarWidth = ScrollUtils.measureScrollBarThickness(mainScrollContainer!, "vertical");
return this.props.renderScrollIndicatorOverlay?.(scrollBarWidth, columnHeaderHeight);
};

// Quadrant-specific renderers
// ===========================

Expand Down
Loading