Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f608867
Use css logic properties
Jan 30, 2022
7ddcbed
Use :dir pseudo class to set row borders
Jan 30, 2022
94aff1a
Fix virtualization
Jan 30, 2022
fa3952c
Use block/inline size instead of height/ width
Jan 30, 2022
3cba825
use start/end with text align
Jan 30, 2022
bf879b4
Adjust context menu styles
Jan 30, 2022
c2e5509
Fix expand icon styles
Jan 31, 2022
860626e
Use padding-block/inline
Jan 31, 2022
41fa638
Fix virtualization and column resize
Jan 31, 2022
7bdcfbd
Merge branch 'main' into am-rtl
amanmahajan7 Jan 31, 2022
250d00b
Add Rtl example
Jan 31, 2022
fbf07db
Revert rename
Jan 31, 2022
81ff94b
scrollTop is positive
Jan 31, 2022
6b7a8a0
Fix margin
Jan 31, 2022
fc203bc
Rename css variables for clarity
Jan 31, 2022
30bc31e
Update src/DataGrid.tsx
amanmahajan7 Feb 1, 2022
bbc8f11
Update src/DataGrid.tsx
amanmahajan7 Feb 1, 2022
37d6141
Update src/DataGrid.tsx
amanmahajan7 Feb 1, 2022
5e4e846
Update website/Nav.tsx
amanmahajan7 Feb 1, 2022
833b6b6
Add missing content menu style, minor cleanup
Feb 1, 2022
d40f551
Add global Right to left checkbox
Feb 1, 2022
d71d651
Add key to create root component when direction is changed
Feb 1, 2022
920bae4
Update readme
Feb 1, 2022
692f669
Fix styling
Feb 1, 2022
79eb126
Fix frozen cell style
Feb 1, 2022
833f188
Fix box shadow
Feb 1, 2022
25dec9e
Add dir prop
Feb 1, 2022
1041e6f
Add direction prop
Feb 1, 2022
f11e3dc
Update examples to use the direction prop
Feb 1, 2022
a69892a
Update README.md
amanmahajan7 Feb 1, 2022
34a13eb
Remove key
Feb 1, 2022
61e8619
Fix resizing
Feb 1, 2022
168cc78
Add key to recreate grid when direction is changed
Feb 1, 2022
a0dba05
Fix direction in portals
Feb 1, 2022
9c5e0a8
Fix arrow direction in rtl
Feb 1, 2022
7704927
Switch left/right keys for groups
Feb 1, 2022
c3ef41f
Merge branch 'main' into am-rtl
Feb 7, 2022
d173762
Update README.md
amanmahajan7 Feb 9, 2022
dffa921
Merge branch 'main' into am-rtl
amanmahajan7 Feb 9, 2022
f6e23b1
Use the direction prop
Feb 9, 2022
0d62d4e
Add direction prop
Feb 9, 2022
0001583
More details on RTL
Feb 9, 2022
132b34a
Update type
Feb 9, 2022
b4dc8e8
Test direction prop
Feb 10, 2022
9a11792
Fix tests
Feb 10, 2022
06270e3
Update README.md
amanmahajan7 Feb 10, 2022
2feb4fe
Move the direction file outside
Feb 10, 2022
1ab2433
Remove dir and use a new sign variable
Feb 10, 2022
3649f3c
Add a comment
Feb 10, 2022
d188c85
Move rtl tests to keyboardNavigation.test
Feb 10, 2022
f391841
Revert "Move rtl tests to keyboardNavigation.test"
Feb 10, 2022
07c5263
Only move the navigation tests to keyboardNavigation.test file
Feb 10, 2022
4929122
Remove confusing comment
Feb 10, 2022
5600176
Key is not required
Feb 10, 2022
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- [Cell copy / pasting](https://adazzle.github.io/react-data-grid/#/all-features)
- [Cell value dragging / filling](https://adazzle.github.io/react-data-grid/#/all-features)
- [Customizable Components](https://adazzle.github.io/react-data-grid/#/customizable-components)
- Right-to-left (RTL) support. We recommend using Firefox as Chrome has a [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1140374) with frozen columns, and the [`:dir` pseudo class](https://developer.mozilla.org/en-US/docs/Web/CSS/:dir) is not supported

## Links

Expand Down Expand Up @@ -232,6 +233,15 @@ function MyGrid() {

###### `rowClass?: Maybe<(row: R) => Maybe<string>>`

##### `direction?: Maybe<'ltr' | 'rtl'>`

This property sets the text direction of the grid, it defaults to `'ltr'` (left-to-right). Setting `direction` to `'rtl'` has the following effects:

- Columns flow from right to left
- Frozen columns are pinned on the right
- Column resize handle is shown on the left edge of the column
- Scrollbar is moved to the left

###### `className?: string | undefined`

###### `style?: CSSProperties | undefined`
Expand Down
41 changes: 24 additions & 17 deletions src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
getColSpan,
max,
sign,
abs,
getSelectedCellColSpan
} from './utils';

Expand All @@ -54,7 +55,8 @@ import type {
SortColumn,
RowHeightArgs,
Maybe,
Components
Components,
Direction
} from './types';

export interface SelectCellState extends Position {
Expand Down Expand Up @@ -169,6 +171,7 @@ export interface DataGridProps<R, SR = unknown, K extends Key = Key> extends Sha
*/
components?: Maybe<Components<R, SR>>;
rowClass?: Maybe<(row: R) => Maybe<string>>;
direction?: Maybe<Direction>;
'data-testid'?: Maybe<string>;
}

Expand Down Expand Up @@ -216,6 +219,7 @@ function DataGrid<R, SR, K extends Key>(
className,
style,
rowClass,
direction,
// ARIA
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
Expand All @@ -238,6 +242,7 @@ function DataGrid<R, SR, K extends Key>(
const noRowsFallback = components?.noRowsFallback ?? defaultComponents?.noRowsFallback;
const cellNavigationMode = rawCellNavigationMode ?? 'NONE';
enableVirtualization ??= true;
direction ??= 'ltr';

/**
* states
Expand Down Expand Up @@ -270,6 +275,9 @@ function DataGrid<R, SR, K extends Key>(
const clientHeight = gridHeight - headerRowHeight - summaryRowsCount * summaryRowHeight;
const isSelectable = selectedRows != null && onSelectedRowsChange != null;
const isHeaderRowSelected = selectedPosition.rowIdx === -1;
const isRtl = direction === 'rtl';
const leftKey = isRtl ? 'ArrowRight' : 'ArrowLeft';
const rightKey = isRtl ? 'ArrowLeft' : 'ArrowRight';

const defaultGridComponents = useMemo(
() => ({
Expand Down Expand Up @@ -566,9 +574,9 @@ function DataGrid<R, SR, K extends Key>(
isGroupRow(row) &&
selectedPosition.idx === -1 &&
// Collapse the current group row if it is focused and is in expanded state
((key === 'ArrowLeft' && row.isExpanded) ||
((key === leftKey && row.isExpanded) ||
// Expand the current group row if it is focused and is in collapsed state
(key === 'ArrowRight' && !row.isExpanded))
(key === rightKey && !row.isExpanded))
) {
event.preventDefault(); // Prevents scrolling
toggleGroup(row.id);
Expand Down Expand Up @@ -600,7 +608,8 @@ function DataGrid<R, SR, K extends Key>(
function handleScroll(event: React.UIEvent<HTMLDivElement>) {
const { scrollTop, scrollLeft } = event.currentTarget;
setScrollTop(scrollTop);
setScrollLeft(scrollLeft);
// scrollLeft is nagative when direction is rtl
setScrollLeft(abs(scrollLeft));
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is negative in RTL

onScroll?.(event);
}

Expand Down Expand Up @@ -749,10 +758,11 @@ function DataGrid<R, SR, K extends Key>(

const isCellAtLeftBoundary = left < scrollLeft + totalFrozenColumnWidth;
const isCellAtRightBoundary = right > clientWidth + scrollLeft;
const sign = isRtl ? -1 : 1;
if (isCellAtLeftBoundary) {
current.scrollLeft = left - totalFrozenColumnWidth;
current.scrollLeft = (left - totalFrozenColumnWidth) * sign;
} else if (isCellAtRightBoundary) {
current.scrollLeft = right - clientWidth;
current.scrollLeft = (right - clientWidth) * sign;
}
}

Expand All @@ -775,13 +785,7 @@ function DataGrid<R, SR, K extends Key>(
const isRowSelected = selectedCellIsWithinSelectionBounds && idx === -1;

// If a group row is focused, and it is collapsed, move to the parent group row (if there is one).
if (
key === 'ArrowLeft' &&
isRowSelected &&
isGroupRow(row) &&
!row.isExpanded &&
row.level !== 0
) {
if (key === leftKey && isRowSelected && isGroupRow(row) && !row.isExpanded && row.level !== 0) {
let parentRowIdx = -1;
for (let i = selectedPosition.rowIdx - 1; i >= 0; i--) {
const parentRow = rows[i];
Expand All @@ -801,9 +805,9 @@ function DataGrid<R, SR, K extends Key>(
case 'ArrowDown':
return { idx, rowIdx: rowIdx + 1 };
case 'ArrowLeft':
return { idx: idx - 1, rowIdx };
return isRtl ? { idx: idx + 1, rowIdx } : { idx: idx - 1, rowIdx };
case 'ArrowRight':
return { idx: idx + 1, rowIdx };
return isRtl ? { idx: idx - 1, rowIdx } : { idx: idx + 1, rowIdx };
case 'Tab':
return { idx: idx + (shiftKey ? -1 : 1), rowIdx };
case 'Home':
Expand Down Expand Up @@ -1117,16 +1121,18 @@ function DataGrid<R, SR, K extends Key>(
...style,
gridTemplateRows: templateRows,
'--rdg-header-row-height': `${headerRowHeight}px`,
'--rdg-row-width': `${totalColumnWidth}px`,
'--rdg-grid-inline-size': `${totalColumnWidth}px`,
'--rdg-summary-row-height': `${summaryRowHeight}px`,
'--rdg-grid-height': `${
'--rdg-grid-block-size': `${
max(totalRowHeight, clientHeight) +
headerRowHeight +
summaryRowsCount * summaryRowHeight
}px`,
'--rdg-sign': isRtl ? -1 : 1,
...getLayoutCssVars()
} as unknown as React.CSSProperties
}
dir={direction}
ref={gridRef}
onScroll={handleScroll}
onKeyDown={handleKeyDown}
Expand Down Expand Up @@ -1156,6 +1162,7 @@ function DataGrid<R, SR, K extends Key>(
selectedCellIdx={isHeaderRowSelected ? selectedPosition.idx : undefined}
selectCell={selectHeaderCellLatest}
shouldFocusGrid={!selectedCellIsWithinSelectionBounds}
direction={direction}
/>
{rows.length === 0 && noRowsFallback ? (
noRowsFallback
Expand Down
12 changes: 6 additions & 6 deletions src/DragHandle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import type { DataGridProps, SelectCellState } from './DataGrid';
const cellDragHandle = css`
cursor: move;
position: absolute;
right: 0;
bottom: 0;
width: 8px;
height: 8px;
inset-inline-end: 0;
inset-block-end: 0;
inline-size: 8px;
block-size: 8px;
background-color: var(--rdg-selection-color);

&:hover {
width: 16px;
height: 16px;
inline-size: 16px;
block-size: 16px;
border: 2px solid var(--rdg-selection-color);
background-color: var(--rdg-background-color);
}
Expand Down
2 changes: 1 addition & 1 deletion src/GroupRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const groupRow = css`
}

> .${cell}:not(:last-child):not(.${cellFrozenLast}) {
border-right: none;
border-inline-end: none;
}
`;

Expand Down
24 changes: 14 additions & 10 deletions src/HeaderCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const cellResizable = css`
content: '';
cursor: col-resize;
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 10px;
inset-block-start: 0;
inset-inline-end: 0;
inset-block-end: 0;
inline-size: 10px;
}
`;

Expand All @@ -31,6 +31,7 @@ type SharedHeaderRowProps<R, SR> = Pick<
| 'selectCell'
| 'onColumnResize'
| 'shouldFocusGrid'
| 'direction'
>;

export interface HeaderCellProps<R, SR> extends SharedHeaderRowProps<R, SR> {
Expand All @@ -49,8 +50,10 @@ export default function HeaderCell<R, SR>({
sortColumns,
onSortColumnsChange,
selectCell,
shouldFocusGrid
shouldFocusGrid,
direction
}: HeaderCellProps<R, SR>) {
const isRtl = direction === 'rtl';
const { ref, tabIndex, onFocus } = useRovingCellRef(isCellSelected);
const sortIndex = sortColumns?.findIndex((sort) => sort.columnKey === column.key);
const sortColumn =
Expand All @@ -72,16 +75,17 @@ export default function HeaderCell<R, SR>({
}

const { currentTarget, pointerId } = event;
const { right } = currentTarget.getBoundingClientRect();
const offset = right - event.clientX;
const { right, left } = currentTarget.getBoundingClientRect();
const offset = isRtl ? event.clientX - left : right - event.clientX;

if (offset > 11) {
// +1px to account for the border size
return;
}

function onPointerMove(event: PointerEvent) {
const width = event.clientX + offset - currentTarget.getBoundingClientRect().left;
const { right, left } = currentTarget.getBoundingClientRect();
const width = isRtl ? right + offset - event.clientX : event.clientX + offset - left;
if (width > 0) {
onColumnResize(column, width);
}
Expand Down Expand Up @@ -139,8 +143,8 @@ export default function HeaderCell<R, SR>({
}

function onDoubleClick(event: React.MouseEvent<HTMLDivElement>) {
const { right } = event.currentTarget.getBoundingClientRect();
const offset = right - event.clientX;
const { right, left } = event.currentTarget.getBoundingClientRect();
const offset = isRtl ? event.clientX - left : right - event.clientX;

if (offset > 11) {
// +1px to account for the border size
Expand Down
9 changes: 6 additions & 3 deletions src/HeaderRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import clsx from 'clsx';
import { css } from '@linaria/core';

import HeaderCell from './HeaderCell';
import type { CalculatedColumn } from './types';
import type { CalculatedColumn, Direction } from './types';
import { getColSpan, getRowStyle } from './utils';
import type { DataGridProps } from './DataGrid';
import { cell, cellFrozen, rowSelectedClassname } from './style';
Expand All @@ -22,6 +22,7 @@ export interface HeaderRowProps<R, SR, K extends React.Key> extends SharedDataGr
lastFrozenColumnIndex: number;
selectedCellIdx: number | undefined;
shouldFocusGrid: boolean;
direction: Direction;
}

const headerRow = css`
Expand All @@ -34,7 +35,7 @@ const headerRow = css`
/* Should have a higher value than 1 to show up above frozen cells */
z-index: 2;
position: sticky;
top: 0;
inset-block-start: 0;
}

> .${cellFrozen} {
Expand All @@ -54,7 +55,8 @@ function HeaderRow<R, SR, K extends React.Key>({
lastFrozenColumnIndex,
selectedCellIdx,
selectCell,
shouldFocusGrid
shouldFocusGrid,
direction
}: HeaderRowProps<R, SR, K>) {
const cells = [];
for (let index = 0; index < columns.length; index++) {
Expand All @@ -77,6 +79,7 @@ function HeaderRow<R, SR, K extends React.Key>({
sortColumns={sortColumns}
selectCell={selectCell}
shouldFocusGrid={shouldFocusGrid && index === 0}
direction={direction}
/>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/SummaryCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import type { CalculatedColumn, CellRendererProps } from './types';
import { useRovingCellRef } from './hooks';

export const summaryCellClassname = css`
top: var(--rdg-summary-row-top);
bottom: var(--rdg-summary-row-bottom);
inset-block-start: var(--rdg-summary-row-top);
inset-block-end: var(--rdg-summary-row-bottom);
`;

interface SharedCellRendererProps<R, SR>
Expand Down
2 changes: 1 addition & 1 deletion src/SummaryRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const summaryRow = css`

const summaryRowBorderClassname = css`
& > .${cell} {
border-top: 2px solid var(--rdg-summary-border-color);
border-block-start: 2px solid var(--rdg-summary-border-color);
}
`;

Expand Down
7 changes: 4 additions & 3 deletions src/editors/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ const textEditor = css`
appearance: none;

box-sizing: border-box;
width: 100%;
height: 100%;
padding: 0px 6px 0 6px;
inline-size: 100%;
block-size: 100%;
padding-block: 0;
padding-inline: 6px;
border: 2px solid #ccc;
vertical-align: top;
color: var(--rdg-color);
Expand Down
6 changes: 3 additions & 3 deletions src/formatters/CheckboxFormatter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const checkboxLabel = css`
justify-content: center;
position: absolute;
inset: 0;
margin-right: 1px; /* align checkbox in row group cell */
margin-inline-end: 1px; /* align checkbox in row group cell */
`;

const checkboxLabelClassname = `rdg-checkbox-label ${checkboxLabel}`;
Expand All @@ -24,8 +24,8 @@ const checkboxInputClassname = `rdg-checkbox-input ${checkboxInput}`;

const checkbox = css`
content: '';
width: 20px;
height: 20px;
inline-size: 20px;
block-size: 20px;
border: 2px solid var(--rdg-border-color);
background-color: var(--rdg-background-color);
.${checkboxInput}:checked + & {
Expand Down
2 changes: 1 addition & 1 deletion src/formatters/ToggleGroupFormatter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const groupCellContent = css`
const groupCellContentClassname = `rdg-group-cell-content ${groupCellContent}`;

const caret = css`
margin-left: 4px;
margin-inline-start: 4px;
stroke: currentColor;
stroke-width: 1.5px;
fill: transparent;
Expand Down
7 changes: 4 additions & 3 deletions src/style/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { css } from '@linaria/core';
export const cell = css`
contain: strict;
contain: size layout style paint;
padding: 0 8px;
border-right: 1px solid var(--rdg-border-color);
border-bottom: 1px solid var(--rdg-border-color);
padding-block: 0;
padding-inline: 8px;
border-inline-end: 1px solid var(--rdg-border-color);
border-block-end: 1px solid var(--rdg-border-color);
grid-row-start: var(--rdg-grid-row-start);
background-color: inherit;

Expand Down
Loading