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

port-changes - frozen columns #1

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
75851b7
port-changes - frozen columns
Matangub Jan 12, 2025
4244830
this fixes the scroll behavior
Matangub Jan 12, 2025
042ac99
small adjustment to the hover color
Matangub Jan 13, 2025
6cef148
removed /lib and /dist from the gitignore file
Matangub Jan 13, 2025
b431e54
Merge branch 'main' into port-changes
Matangub Jan 22, 2025
249c111
update types
Matangub Jan 22, 2025
72028d5
fix attempt
Matangub Jan 22, 2025
2ab2c16
remove changes for this
Matangub Jan 22, 2025
a58c40f
added PaddingInlineEnd and fixed comments
Matangub Jan 28, 2025
6049589
prettier
Matangub Jan 28, 2025
b8ae53f
fixed useMemo dependencies
Matangub Jan 28, 2025
876a7e0
updated ci.yml
Matangub Jan 29, 2025
7867829
name update to trigger workflow again
Matangub Jan 29, 2025
2220b8c
attempt to fix with node version
Matangub Jan 29, 2025
0a53eaf
attempt to fix broken typecheck
Matangub Jan 29, 2025
1f41abc
remove typecheck
Matangub Jan 29, 2025
209c687
attempt to fix ci with legacy peer deps and npmrc
Matangub Jan 29, 2025
af5477b
update strategy to only run for 18
Matangub Jan 29, 2025
64a1ef2
attempt to make the CI work
Matangub Jan 29, 2025
f132378
attempt to skip some steps just to see if it works
Matangub Jan 29, 2025
ea384f7
remove react 18 things
Matangub Jan 29, 2025
d070667
version 1.0.0 and changed description
Matangub Jan 30, 2025
bd3df0b
fix: frozen right columns should not focus on click
Matangub Jan 30, 2025
0383f88
added a CI script to publish it directly to github packages
Matangub Feb 2, 2025
ae3ee11
added workflow_dispatch
Matangub Feb 2, 2025
1c51267
changed version to 1.0.2-beta
Matangub Feb 2, 2025
3ed35c4
update nodejs version
Matangub Feb 2, 2025
4140400
1.0.3-beta version bump
Matangub Feb 2, 2025
b98c6fc
remove github publish workflow
Matangub Feb 5, 2025
790edb5
cr fixes + bump version to 1.0.2
Matangub Feb 5, 2025
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
65 changes: 0 additions & 65 deletions .github/workflows/ci.yml

This file was deleted.

10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
{
"name": "react-data-grid",
"version": "7.0.0-beta.47",
"name": "@port-labs/port-react-data-grid",
"version": "1.0.2",
"description": "Forked version of @adazzle/react-data-grid with custom changes by Port Labs",
"license": "MIT",
"description": "Feature-rich and customizable data grid React component",
"keywords": [
"react",
"data grid"
],
"repository": {
"type": "git",
"url": "git+https://github.com/adazzle/react-data-grid.git"
"type": "git"
},
"bugs": "https://github.com/adazzle/react-data-grid/issues",
"type": "module",
"exports": {
"./lib/styles.css": "./lib/styles.css",
Expand Down
17 changes: 13 additions & 4 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,9 @@ function DataGrid<R, SR, K extends Key>(
colOverscanEndIdx,
templateColumns,
layoutCssVars,
totalFrozenColumnWidth
totalFrozenColumnWidth,
rightFrozenColumnCount,
totalRightFrozenColumnWidth
} = useCalculatedColumns({
rawColumns,
defaultColumnOptions,
Expand Down Expand Up @@ -424,7 +426,8 @@ function DataGrid<R, SR, K extends Key>(
rowOverscanEndIdx,
rows,
topSummaryRows,
bottomSummaryRows
bottomSummaryRows,
rightFrozenColumnCount
});

const { gridTemplateColumns, handleColumnResize } = useColumnWidths(
Expand Down Expand Up @@ -476,7 +479,10 @@ function DataGrid<R, SR, K extends Key>(
const cell = getCellToScroll(gridRef.current!);
if (cell === null) return;

scrollIntoView(cell);
const isFrozen = cell.classList.contains('rdg-cell-frozen');
if(!isFrozen) {
scrollIntoView(cell);
}
// Focus cell content when available instead of the cell itself
const elementToFocus = cell.querySelector<Element & HTMLOrSVGElement>('[tabindex="0"]') ?? cell;
elementToFocus.focus({ preventScroll: true });
Expand Down Expand Up @@ -1078,7 +1084,6 @@ function DataGrid<R, SR, K extends Key>(

const isGroupRowFocused =
selectedPosition.idx === -1 && selectedPosition.rowIdx !== minRowIdx - 1;

return (
// biome-ignore lint/a11y/useValidAriaProps: aria-description is a valid prop
<div
Expand All @@ -1105,6 +1110,10 @@ function DataGrid<R, SR, K extends Key>(
selectedPosition.idx > lastFrozenColumnIndex || scrollToPosition?.idx !== undefined
? `${totalFrozenColumnWidth}px`
: undefined,
scrollPaddingInlineEnd:
rightFrozenColumnCount < maxRowIdx || scrollToPosition?.idx !== undefined
? `${totalRightFrozenColumnWidth}px`
: undefined,
scrollPaddingBlock:
isRowIdxWithinViewportBounds(selectedPosition.rowIdx) ||
scrollToPosition?.rowIdx !== undefined
Expand Down
7 changes: 6 additions & 1 deletion src/HeaderCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ export const resizeHandleClassname = css`
inset-block-start: 0;
inset-inline-end: 0;
inset-block-end: 0;
inline-size: 10px;
inline-size: 4px;

&:hover {
background: var(--rdg-selection-color);
padding: 4px 0;
}
}
`;

Expand Down
105 changes: 81 additions & 24 deletions src/hooks/useCalculatedColumns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,21 @@ export function useCalculatedColumns<R, SR>({
const defaultResizable = defaultColumnOptions?.resizable ?? false;
const defaultDraggable = defaultColumnOptions?.draggable ?? false;

const { columns, colSpanColumns, lastFrozenColumnIndex, headerRowsCount } = useMemo((): {
const {
columns,
colSpanColumns,
lastFrozenColumnIndex,
rightFrozenColumnCount,
headerRowsCount
} = useMemo((): {
readonly columns: readonly CalculatedColumn<R, SR>[];
readonly colSpanColumns: readonly CalculatedColumn<R, SR>[];
readonly lastFrozenColumnIndex: number;
readonly rightFrozenColumnCount: number;
readonly headerRowsCount: number;
} => {
let lastFrozenColumnIndex = -1;
let rightFrozenColumnCount = 0;
let headerRowsCount = 1;
const columns: MutableCalculatedColumn<R, SR>[] = [];

Expand All @@ -85,13 +93,15 @@ export function useCalculatedColumns<R, SR>({
}

const frozen = rawColumn.frozen ?? false;
const rightFrozen = rawColumn.rightFrozen ?? false;

const column: MutableCalculatedColumn<R, SR> = {
...rawColumn,
parent,
idx: 0,
level: 0,
frozen,
rightFrozen,
width: rawColumn.width ?? defaultWidth,
minWidth: rawColumn.minWidth ?? defaultMinWidth,
maxWidth: rawColumn.maxWidth ?? defaultMaxWidth,
Expand All @@ -107,29 +117,45 @@ export function useCalculatedColumns<R, SR>({
lastFrozenColumnIndex++;
}

if (rightFrozen) {
rightFrozenColumnCount++;
}

if (level > headerRowsCount) {
headerRowsCount = level;
}
}
}

columns.sort(({ key: aKey, frozen: frozenA }, { key: bKey, frozen: frozenB }) => {
// Sort select column first:
if (aKey === SELECT_COLUMN_KEY) return -1;
if (bKey === SELECT_COLUMN_KEY) return 1;
columns.sort(
(
{ key: aKey, frozen: frozenA, rightFrozen: rightFrozenA },
{ key: bKey, frozen: frozenB, rightFrozen: rightFrozenB }
) => {
// Sort select column first:
if (aKey === SELECT_COLUMN_KEY) return -1;
if (bKey === SELECT_COLUMN_KEY) return 1;

// Sort frozen columns second:
if (frozenA) {
if (frozenB) return 0;
return -1;
}
if (frozenB) return 1;

// Sort frozen columns second:
if (frozenA) {
if (frozenB) return 0;
return -1;
}
if (frozenB) return 1;
// Sort right frozen columns second:
if (rightFrozenA) {
if (rightFrozenB) return 0;
return 1;
}
if (rightFrozenB) return -1;

// TODO: sort columns to keep them grouped if they have a parent
// TODO: sort columns to keep them grouped if they have a parent

// Sort other columns last:
return 0;
});
// Sort other columns last:
return 0;
}
);

const colSpanColumns: CalculatedColumn<R, SR>[] = [];
columns.forEach((column, idx) => {
Expand All @@ -145,6 +171,7 @@ export function useCalculatedColumns<R, SR>({
columns,
colSpanColumns,
lastFrozenColumnIndex,
rightFrozenColumnCount,
headerRowsCount
};
}, [
Expand All @@ -158,15 +185,23 @@ export function useCalculatedColumns<R, SR>({
defaultDraggable
]);

const { templateColumns, layoutCssVars, totalFrozenColumnWidth, columnMetrics } = useMemo((): {
const {
templateColumns,
layoutCssVars,
totalFrozenColumnWidth,
totalRightFrozenColumnWidth,
columnMetrics
} = useMemo((): {
templateColumns: readonly string[];
layoutCssVars: Readonly<Record<string, string>>;
totalFrozenColumnWidth: number;
totalRightFrozenColumnWidth: number;
columnMetrics: ReadonlyMap<CalculatedColumn<R, SR>, ColumnMetric>;
} => {
const columnMetrics = new Map<CalculatedColumn<R, SR>, ColumnMetric>();
let left = 0;
let totalFrozenColumnWidth = 0;
let totalRightFrozenColumnWidth = 0;
const templateColumns: string[] = [];

for (const column of columns) {
Expand All @@ -191,24 +226,42 @@ export function useCalculatedColumns<R, SR>({

const layoutCssVars: Record<string, string> = {};

if (rightFrozenColumnCount !== 0) {
let rightEnd = 0;
for (let i = columns.length - 1; i >= columns.length - rightFrozenColumnCount; i--) {
const column = columns[i];
const columnMetric = columnMetrics.get(column)!;
totalRightFrozenColumnWidth += columnMetric.width;
layoutCssVars[`--rdg-frozen-right-${column.idx}`] = `${rightEnd}px`;
rightEnd += columnMetric.width;
}
}

for (let i = 0; i <= lastFrozenColumnIndex; i++) {
const column = columns[i];
layoutCssVars[`--rdg-frozen-left-${column.idx}`] = `${columnMetrics.get(column)!.left}px`;
}

return { templateColumns, layoutCssVars, totalFrozenColumnWidth, columnMetrics };
}, [getColumnWidth, columns, lastFrozenColumnIndex]);
return {
templateColumns,
layoutCssVars,
totalFrozenColumnWidth,
totalRightFrozenColumnWidth,
columnMetrics
};
}, [getColumnWidth, columns, lastFrozenColumnIndex, rightFrozenColumnCount]);

const [colOverscanStartIdx, colOverscanEndIdx] = useMemo((): [number, number] => {
if (!enableVirtualization) {
return [0, columns.length - 1];
}
// get the viewport's left side and right side positions for non-frozen columns
const viewportLeft = scrollLeft + totalFrozenColumnWidth;
const viewportRight = scrollLeft + viewportWidth;
const viewportRight = scrollLeft + viewportWidth - totalRightFrozenColumnWidth;
// get first and last non-frozen column indexes
const lastColIdx = columns.length - 1;
const firstUnfrozenColumnIdx = min(lastFrozenColumnIndex + 1, lastColIdx);
const lastUnfrozonColumnIdx = min(columns.length - rightFrozenColumnCount - 1, lastColIdx);

// skip rendering non-frozen columns if the frozen columns cover the entire viewport
if (viewportLeft >= viewportRight) {
Expand All @@ -217,7 +270,7 @@ export function useCalculatedColumns<R, SR>({

// get the first visible non-frozen column index
let colVisibleStartIdx = firstUnfrozenColumnIdx;
while (colVisibleStartIdx < lastColIdx) {
while (colVisibleStartIdx < lastUnfrozonColumnIdx) {
const { left, width } = columnMetrics.get(columns[colVisibleStartIdx])!;
// if the right side of the columnn is beyond the left side of the available viewport,
// then it is the first column that's at least partially visible
Expand All @@ -229,7 +282,7 @@ export function useCalculatedColumns<R, SR>({

// get the last visible non-frozen column index
let colVisibleEndIdx = colVisibleStartIdx;
while (colVisibleEndIdx < lastColIdx) {
while (colVisibleEndIdx < lastUnfrozonColumnIdx) {
const { left, width } = columnMetrics.get(columns[colVisibleEndIdx])!;
// if the right side of the column is beyond or equal to the right side of the available viewport,
// then it the last column that's at least partially visible, as the previous column's right side is not beyond the viewport.
Expand All @@ -240,7 +293,7 @@ export function useCalculatedColumns<R, SR>({
}

const colOverscanStartIdx = max(firstUnfrozenColumnIdx, colVisibleStartIdx - 1);
const colOverscanEndIdx = min(lastColIdx, colVisibleEndIdx + 1);
const colOverscanEndIdx = min(lastUnfrozonColumnIdx, colVisibleEndIdx + 1);

return [colOverscanStartIdx, colOverscanEndIdx];
}, [
Expand All @@ -249,8 +302,10 @@ export function useCalculatedColumns<R, SR>({
lastFrozenColumnIndex,
scrollLeft,
totalFrozenColumnWidth,
totalRightFrozenColumnWidth,
viewportWidth,
enableVirtualization
enableVirtualization,
rightFrozenColumnCount
]);

return {
Expand All @@ -262,7 +317,9 @@ export function useCalculatedColumns<R, SR>({
layoutCssVars,
headerRowsCount,
lastFrozenColumnIndex,
totalFrozenColumnWidth
totalFrozenColumnWidth,
rightFrozenColumnCount,
totalRightFrozenColumnWidth
};
}

Expand Down
Loading