Skip to content

Commit

Permalink
Improve multi cell selection for horizontal layout and release versio…
Browse files Browse the repository at this point in the history
…n patch
  • Loading branch information
radubrehar committed Oct 9, 2024
1 parent 12c814e commit 72ba3ce
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import * as React from 'react';

import {
InfiniteTable,
InfiniteTablePropColumns,
useInfiniteColumnFilterEditor,
} from '@infinite-table/infinite-react';
import { DataSource } from '@infinite-table/infinite-react';

type Developer = {
id: number;
firstName: string;
lastName: string;

currency: string;
preferredLanguage: string;
stack: string;
canDesign: 'yes' | 'no';

salary: number;
};

const data: Developer[] = [
{
id: 1,
firstName: 'John',
lastName: 'Bob',
salary: 2000,
canDesign: 'yes',
currency: 'USD',
preferredLanguage: 'JavaScript',
stack: 'frontend',
},
{
id: 2,
firstName: 'Marry',
lastName: 'Bob',
salary: 3500,
canDesign: 'yes',
currency: 'USD',
preferredLanguage: 'JavaScript',
stack: 'frontend',
},
{
id: 3,
firstName: 'Bill',
lastName: 'Bobson',
salary: 3000,
canDesign: 'no',
currency: 'CAD',
preferredLanguage: 'TypeScript',
stack: 'frontend',
},
{
id: 4,
firstName: 'Mark',
lastName: 'Twain',
salary: 1000,
canDesign: 'yes',
currency: 'CAD',
preferredLanguage: 'Rust',
stack: 'backend',
},
{
id: 5,
firstName: 'Matthew',
lastName: 'Hilson',
salary: 12900,
canDesign: 'yes',
currency: 'CAD',
preferredLanguage: 'Go',
stack: 'backend',
},
];
import { defaultFilterTypes } from '@infinite-table/infinite-react';

console.log(defaultFilterTypes);

const includesOperator = defaultFilterTypes.string.operators.find(
(op) => op.name === 'includes',
);

includesOperator!.fn = ({ currentValue, filterValue }) => {
if (filterValue && filterValue.startsWith('-')) {
return !currentValue
.toLowerCase()
.includes(filterValue.slice(1).toLowerCase());
}
return (
typeof currentValue === 'string' &&
typeof filterValue == 'string' &&
currentValue.toLowerCase().includes(filterValue.toLowerCase())
);
};

const columns: InfiniteTablePropColumns<Developer> = {
id: {
field: 'id',
},
firstName: {
field: 'firstName',
},
salary: {
defaultFilterable: true,
field: 'salary',
type: 'number',
filterType: 'salary',
},
stack: { field: 'stack' },
currency: { field: 'currency', defaultFilterable: false },
};

export default () => {
return (
<>
<React.StrictMode>
<DataSource<Developer>
data={data}
primaryKey="id"
defaultFilterValue={[]}
filterDelay={0}
filterTypes={{
salary: {
defaultOperator: '',
emptyValues: [],
components: {
FilterEditor: () => {
const { operator, filtered } =
useInfiniteColumnFilterEditor();
return (
<div data-operator="default-filter-type-editor">
{filtered ? (
<>Operator {operator?.name}</>
) : (
'Not applied'
)}
</div>
);
},
},
operators: [
{
name: 'low',
fn: ({ currentValue, filterValue, emptyValues }) => {
if (
emptyValues.includes(currentValue) ||
emptyValues.includes(filterValue)
) {
return true;
}
return currentValue <= 1000;
},
},
{
name: 'medium',
fn: ({ currentValue }) => {
return currentValue > 1000 && currentValue < 10000;
},

components: {
FilterEditor: () => (
<div data-operator="medium">Medium</div>
),
},
},
{
name: 'high',
fn: ({ currentValue }) => {
return currentValue >= 10000;
},
components: {
FilterEditor: () => <div data-operator="high">High</div>,
},
},
],
},
}}
>
<InfiniteTable<Developer>
domProps={{
style: {
height: '100%',
},
}}
columnDefaultWidth={150}
columnMinWidth={50}
columns={columns}
/>
</DataSource>
</React.StrictMode>
</>
);
};
24 changes: 1 addition & 23 deletions source/src/components/InfiniteTable/api/getCellSelectionApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getRowInfoArray,
getRowInfoAt,
} from '../../DataSource/dataSourceGetters';
import { CellPositionByIndex } from '../../types/CellPositionByIndex';
import { ensureMinMaxCellPositionByIndex } from '../../types/CellPositionByIndex';
import { InfiniteTableComputedValues, InfiniteTableRowInfo } from '../types';
import { CellPositionOptions } from './type';

Expand All @@ -25,28 +25,6 @@ function ensureSortedPerOrder<T>(arr: T[], sortPattern: T[]) {
.filter((x: T | null) => x != null) as T[];
}

export function ensureMinMaxCellPositionByIndex(
start: CellPositionByIndex,
end: CellPositionByIndex,
) {
let { rowIndex: startRowIndex, colIndex: startColIndex } = start;
let { rowIndex: endRowIndex, colIndex: endColIndex } = end;

const [colStart, colEnd] =
startColIndex > endColIndex
? [endColIndex, startColIndex]
: [startColIndex, endColIndex];

const [rowStart, rowEnd] =
startRowIndex > endRowIndex
? [endRowIndex, startRowIndex]
: [startRowIndex, endRowIndex];

return [
{ rowIndex: rowStart, colIndex: colStart },
{ rowIndex: rowEnd, colIndex: colEnd },
];
}
export type InfiniteTableCellSelectionApi<T> = {
isCellSelected(cellPosition: CellPositionOptions): boolean;
selectCell(cellPosition: CellPositionOptions & { clear?: boolean }): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ import { InfiniteTableActions } from '../types/InfiniteTableState';
export type InfiniteTableEventHandlerAbstractContext<T> = {
getComputed: () => InfiniteTableComputedValues<T>;
getState: () => {
wrapRowsHorizontally: InfiniteTableState<T>['wrapRowsHorizontally'];
activeRowIndex: InfiniteTableState<T>['activeRowIndex'];
activeCellIndex: InfiniteTableState<T>['activeCellIndex'];
keyboardNavigation: InfiniteTableState<T>['keyboardNavigation'];
keyboardSelection: InfiniteTableState<T>['keyboardSelection'];
brain: InfiniteTableState<T>['brain'];
};
actions: InfiniteTableActions<T>;
cloneRowSelection: (
Expand Down
20 changes: 18 additions & 2 deletions source/src/components/InfiniteTable/eventHandlers/onCellClick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export function updateCellSelectionOnCellClick<T>(
) {
const {
getDataSourceState,
getState,
getComputed,
rowIndex,
colIndex,
Expand All @@ -77,7 +78,10 @@ export function updateCellSelectionOnCellClick<T>(
return;
}

const { multiCellSelector } = getComputed();
const { multiCellSelector, computedVisibleColumns } = getComputed();
const { brain } = getState();
const { rowsPerPage } = brain;
const columnsPerSet = computedVisibleColumns.length;

const cellSelection = new CellSelectionState(existingCellSelection);

Expand All @@ -91,7 +95,19 @@ export function updateCellSelectionOnCellClick<T>(
if (event.metaKey || event.ctrlKey) {
multiCellSelector.singleAddClick(position);
} else if (event.shiftKey) {
multiCellSelector.multiSelectClick(position);
const horizontalLayout = !!getState().wrapRowsHorizontally;
multiCellSelector.multiSelectClick(
position,
horizontalLayout
? {
horizontalLayout,
rowsPerPage,
columnsPerSet,
}
: {
horizontalLayout,
},
);
} else {
multiCellSelector.resetClick(position);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useEffect } from 'react';
import { HorizontalLayoutMatrixBrain } from '../../VirtualBrain/HorizontalLayoutMatrixBrain';

import { useInfiniteTable } from './useInfiniteTable';

Expand All @@ -23,8 +22,9 @@ export function useHorizontalLayout() {

let changes = false;

const rowsPerPage = (brain as HorizontalLayoutMatrixBrain).rowsPerPage;
const newRowsPerPage = groupBy && groupBy.length > 0 ? rowsPerPage : null;
const rowsPerPage = brain.rowsPerPage;
const newRowsPerPage =
groupBy && groupBy.length > 0 && rowsPerPage > 0 ? rowsPerPage : null;

if (currentRowsPerPage != newRowsPerPage) {
dataSourceActions.rowsPerPage = newRowsPerPage;
Expand Down
Loading

0 comments on commit 72ba3ce

Please sign in to comment.