diff --git a/README.md b/README.md index 2940542996..0ec4478d70 100644 --- a/README.md +++ b/README.md @@ -187,9 +187,6 @@ The DataGrid supports the following CSS variables for customization: --rdg-summary-border-width: calc(var(--rdg-border-width) * 2); --rdg-summary-border-color: light-dark(#aaa, #555); - /* Frozen columns */ - --rdg-cell-frozen-box-shadow: 2px 0 5px -2px rgba(136, 136, 136, 0.3); - /* Checkboxes */ --rdg-checkbox-focus-color: hsl(207deg 100% 69%); } diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 71ee3dc72a..d6abea1d42 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -69,7 +69,12 @@ import type { PartialPosition } from './ScrollToCell'; import ScrollToCell from './ScrollToCell'; import { default as defaultRenderSortStatus } from './sortStatus'; import { cellDragHandleClassname, cellDragHandleFrozenClassname } from './style/cell'; -import { rootClassname, viewportDraggingClassname } from './style/core'; +import { + rootClassname, + frozenColumnShadowClassname, + viewportDraggingClassname, + frozenColumnShadowTopClassname +} from './style/core'; import SummaryRow from './SummaryRow'; export interface SelectCellState extends Position { @@ -368,6 +373,10 @@ export function DataGrid(props: DataGridPr const minRowIdx = -headerAndTopSummaryRowsCount; const mainHeaderRowIdx = minRowIdx + groupedColumnHeaderRowsCount; const maxRowIdx = rows.length + bottomSummaryRowsCount - 1; + const frozenShadowStyles: React.CSSProperties = { + gridColumnStart: lastFrozenColumnIndex + 2, + insetInlineStart: totalFrozenColumnWidth + }; const [selectedPosition, setSelectedPosition] = useState( (): SelectCellState | EditCellState => ({ idx: -1, rowIdx: minRowIdx - 1, mode: 'SELECT' }) @@ -1269,11 +1278,11 @@ export function DataGrid(props: DataGridPr const isSummaryRowSelected = selectedPosition.rowIdx === summaryRowIdx; const top = clientHeight > totalRowHeight - ? gridHeight - summaryRowHeight * (bottomSummaryRows.length - rowIdx) + ? gridHeight - summaryRowHeight * (bottomSummaryRowsCount - rowIdx) : undefined; const bottom = top === undefined - ? summaryRowHeight * (bottomSummaryRows.length - 1 - rowIdx) + ? summaryRowHeight * (bottomSummaryRowsCount - 1 - rowIdx) : undefined; return ( @@ -1298,6 +1307,47 @@ export function DataGrid(props: DataGridPr )} + {lastFrozenColumnIndex > -1 && ( + <> +
+ + {rows.length > 0 && ( +
+ )} + + {bottomSummaryRows != null && bottomSummaryRowsCount > 0 && ( +
totalRowHeight + ? gridHeight - summaryRowHeight * bottomSummaryRowsCount + : undefined, + insetBlockEnd: clientHeight > totalRowHeight ? undefined : 0 + }} + /> + )} + + )} + {getDragHandle()} {/* render empty cells that span only 1 column so we can safely measure column widths, regardless of colSpan */} diff --git a/src/style/cell.ts b/src/style/cell.ts index f3d4f3ce1e..f9b9500526 100644 --- a/src/style/cell.ts +++ b/src/style/cell.ts @@ -35,11 +35,6 @@ export const cellFrozen = css` position: sticky; /* Should have a higher value than 0 to show up above unfrozen cells */ z-index: 1; - - /* Add box-shadow on the last frozen cell */ - &:nth-last-child(1 of &) { - box-shadow: var(--rdg-cell-frozen-box-shadow); - } } `; diff --git a/src/style/core.ts b/src/style/core.ts index 0f1be75f2f..5366439716 100644 --- a/src/style/core.ts +++ b/src/style/core.ts @@ -16,7 +16,6 @@ const root = css` --rdg-selection-width: 2px; --rdg-selection-color: hsl(207, 75%, 66%); --rdg-font-size: 14px; - --rdg-cell-frozen-box-shadow: 2px 0 5px -2px rgba(136, 136, 136, 0.3); --rdg-border-width: 1px; --rdg-summary-border-width: calc(var(--rdg-border-width) * 2); --rdg-color: light-dark(#000, #ddd); @@ -38,10 +37,6 @@ const root = css` color-scheme: light; } - &:dir(rtl) { - --rdg-cell-frozen-box-shadow: -2px 0 5px -2px rgba(136, 136, 136, 0.3); - } - display: grid; accent-color: light-dark(hsl(207deg 100% 29%), hsl(207deg 100% 79%)); @@ -59,6 +54,9 @@ const root = css` color: var(--rdg-color); font-size: var(--rdg-font-size); + container-name: rdg-root; + container-type: scroll-state; + /* needed on Firefox to fix scrollbars */ &::before { content: ''; @@ -92,3 +90,35 @@ const viewportDragging = css` `; export const viewportDraggingClassname = `rdg-viewport-dragging ${viewportDragging}`; + +// Add shadow after the last frozen cell +export const frozenColumnShadowClassname = css` + position: sticky; + width: 10px; + background-image: linear-gradient( + to right, + light-dark(rgb(0 0 0 / 15%), rgb(0 0 0 / 40%)), + transparent + ); + pointer-events: none; + z-index: 1; + + opacity: 1; + transition: opacity 0.1s; + + /* TODO: reverse 'opacity' and remove 'not' */ + @container rdg-root not scroll-state(scrollable: inline-start) { + opacity: 0; + } + + &:dir(rtl) { + transform: scaleX(-1); + } +`; + +const topShadowClassname = css` + /* render above header and summary rows */ + z-index: 2; +`; + +export const frozenColumnShadowTopClassname = `${frozenColumnShadowClassname} ${topShadowClassname}`; diff --git a/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-chromium-linux.png b/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-chromium-linux.png index b055c80eb5..d0596683d4 100644 Binary files a/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-chromium-linux.png and b/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-chromium-linux.png differ diff --git a/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-firefox-linux.png b/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-firefox-linux.png index bcfa819d45..94cf6e7ad6 100644 Binary files a/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-firefox-linux.png and b/test/visual/__screenshots__/basicGrid.test.tsx/basic-grid-firefox-linux.png differ diff --git a/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-chromium-linux.png b/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-chromium-linux.png index 784b3ce76d..6d2b679b95 100644 Binary files a/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-chromium-linux.png and b/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-chromium-linux.png differ diff --git a/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-firefox-linux.png b/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-firefox-linux.png index 6c54a4684b..2c3689f586 100644 Binary files a/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-firefox-linux.png and b/test/visual/__screenshots__/treeGrid.test.tsx/tree-grid-firefox-linux.png differ diff --git a/website/routes/CommonFeatures.tsx b/website/routes/CommonFeatures.tsx index b24c187f42..071ae0a654 100644 --- a/website/routes/CommonFeatures.tsx +++ b/website/routes/CommonFeatures.tsx @@ -34,7 +34,7 @@ const dialogContainerClassname = css` inset: 0; display: flex; place-items: center; - background: rgba(0, 0, 0, 0.1); + background: rgb(0 0 0 / 10%); > dialog { width: 300px; diff --git a/website/routes/NoRows.tsx b/website/routes/NoRows.tsx index 93ca3ebbf8..12a8f5147d 100644 --- a/website/routes/NoRows.tsx +++ b/website/routes/NoRows.tsx @@ -15,7 +15,7 @@ const gridClassname = css` function EmptyRowsRenderer() { return ( -
+
Nothing to show{' '} (´・ω・`)