From ee42c576b4c74b1213adc853f25c538ddc3ecc0e Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 14 Dec 2023 11:50:43 -0500 Subject: [PATCH] feat: Update GridTable's cardStyle (#983) Adds 'GridStyle.nonHeaderRowCss' to directly apply styles to non-header row elements. Adds 'GridStyle.rowHoverCss' to apply hover styles to non-header row elements Updates cardStyle to take advantage of the new styles to provide a box-shadow and border color change when hovering over a row. Updates cardStyle to apply more styles directly on the row element rather than on the individual cells --- src/components/Table/GridTable.tsx | 6 +++--- src/components/Table/TableStyles.tsx | 20 +++++++++++--------- src/components/Table/components/Row.tsx | 8 +++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/components/Table/GridTable.tsx b/src/components/Table/GridTable.tsx index e8eac1f14..4d6cb300b 100644 --- a/src/components/Table/GridTable.tsx +++ b/src/components/Table/GridTable.tsx @@ -437,7 +437,7 @@ function renderDiv(
div > *`, style.betweenRowsCss).$ : {}), - ...(style.firstNonHeaderRowCss ? Css.addIn(`& > div:first-of-type > *`, style.firstNonHeaderRowCss).$ : {}), + ...(style.firstNonHeaderRowCss ? Css.addIn(`& > div:first-of-type`, style.firstNonHeaderRowCss).$ : {}), ...(style.lastRowCss && Css.addIn("& > div:last-of-type", style.lastRowCss).$), }} > @@ -475,7 +475,7 @@ function renderTable( ...Css.w100.add("borderCollapse", "separate").add("borderSpacing", "0").$, ...Css.addIn("& > tbody > tr > * ", style.betweenRowsCss || {}) // removes border between header and second row - .addIn("& > tbody > tr:first-of-type > *", style.firstNonHeaderRowCss || {}).$, + .addIn("& > tbody > tr:first-of-type", style.firstNonHeaderRowCss || {}).$, ...Css.addIn("& > tbody > tr:last-of-type", style.lastRowCss).$, ...Css.addIn("& > thead > tr:first-of-type", style.firstRowCss).$, ...style.rootCss, @@ -669,7 +669,7 @@ const VirtualRoot = memoizeOne<(gs: GridStyle, columns: GridColumn[], id: s ...(isHeader ? Css.addIn("& > div:first-of-type > *", gs.firstRowCss).$ : { - ...Css.addIn("& > div:first-of-type > *", gs.firstNonHeaderRowCss).$, + ...Css.addIn("& > div:first-of-type", gs.firstNonHeaderRowCss).$, ...Css.addIn("& > div:last-of-type > *", gs.lastRowCss).$, }), ...gs.rootCss, diff --git a/src/components/Table/TableStyles.tsx b/src/components/Table/TableStyles.tsx index 089ca39fb..97bfcd283 100644 --- a/src/components/Table/TableStyles.tsx +++ b/src/components/Table/TableStyles.tsx @@ -15,6 +15,8 @@ export interface GridStyle { lastRowCss?: Properties; /** Applied on the first row of the table (could be the Header or Totals row). */ firstRowCss?: Properties; + /** Applied to every non-header row of the table */ + nonHeaderRowCss?: Properties; /** Applied to the first non-header row, i.e. if you want to cancel out `betweenRowsCss`. */ firstNonHeaderRowCss?: Properties; /** Applied to all cell divs (via a selector off the base div). */ @@ -39,7 +41,9 @@ export interface GridStyle { /** Applied if there is a fallback/overflow message showing. */ firstRowMessageCss?: Properties; /** Applied on hover if a row has a rowLink/onClick set. */ - rowHoverColor?: Palette; + rowHoverColor?: Palette | "none"; + /** Applied on hover of a row */ + nonHeaderRowHoverCss?: Properties; /** Default content to put into an empty cell */ emptyCell?: ReactNode; presentationSettings?: Pick & @@ -209,18 +213,16 @@ export const condensedStyle: GridStyle = { export const cardStyle: GridStyle = { ...defaultStyle, betweenRowsCss: {}, - firstNonHeaderRowCss: Css.mt2.$, - cellCss: Css.p2.my1.bt.bb.bGray400.$, - firstCellCss: Css.bl.add({ borderTopLeftRadius: "4px", borderBottomLeftRadius: "4px" }).$, - lastCellCss: Css.br.add({ borderTopRightRadius: "4px", borderBottomRightRadius: "4px" }).$, + nonHeaderRowCss: Css.br4.overflowHidden.ba.bGray400.mt2.add("transition", "all 240ms").$, + firstRowCss: Css.bl.br.bGray200.borderRadius("8px 8px 0 0").overflowHidden.$, + cellCss: Css.p2.$, // Undo the card look & feel for the header headerCellCss: { ...defaultStyle.headerCellCss, - ...Css.add({ - border: "none", - borderRadius: "unset", - }).p1.m0.xsMd.gray700.$, + ...Css.p1.m0.xsMd.gray700.$, }, + rowHoverColor: "none", + nonHeaderRowHoverCss: Css.bshHover.bGray700.$, }; export function resolveStyles(style: GridStyle | GridStyleDef): GridStyle { diff --git a/src/components/Table/components/Row.tsx b/src/components/Table/components/Row.tsx index 96d74e3a3..95da77496 100644 --- a/src/components/Table/components/Row.tsx +++ b/src/components/Table/components/Row.tsx @@ -75,15 +75,21 @@ function RowImpl(props: RowProps): ReactElement { const revealOnRowHoverClass = "revealOnRowHover"; - const showRowHoverColor = !reservedRowKinds.includes(row.kind) && !omitRowHover; + const showRowHoverColor = !reservedRowKinds.includes(row.kind) && !omitRowHover && style.rowHoverColor !== "none"; const rowStyleCellCss = maybeApplyFunction(row as any, rowStyle?.cellCss); const rowCss = { + ...(!reservedRowKinds.includes(row.kind) && style.nonHeaderRowCss), // Optionally include the row hover styles, by default they should be turned on. ...(showRowHoverColor && { // Even though backgroundColor is set on the cellCss, the hover target is the row. "&:hover > *": Css.bgColor(style.rowHoverColor ?? Palette.Blue100).$, }), + ...(!reservedRowKinds.includes(row.kind) && + style.nonHeaderRowHoverCss && { + // Need to spread this to make TS happy. + ":hover": { ...style.nonHeaderRowHoverCss }, + }), // For virtual tables use `display: flex` to keep all cells on the same row. For each cell in the row use `flexNone` to ensure they stay their defined widths ...(as === "table" ? {} : Css.relative.df.fg1.fs1.addIn("&>*", Css.flexNone.$).$), // Apply `cursorPointer` to the row if it has a link or `onClick` value.