Skip to content

Commit

Permalink
[PBNTR-666] Custom Cells for Advanced Table First Column (#3889)
Browse files Browse the repository at this point in the history
[Runway Story](https://runway.powerhrg.com/backlog_items/PBNTR-666)

- This story adds the ability to have custom cells for the first column
of the advanced table.
- This functionality was added for the rest of the columns on [this
PR](#3821)
- To test, scroll down to the last doc example on the React side

[csb
here](https://codesandbox.io/p/sandbox/advanced-table-custom-cell-gjzxtw)

---------

Co-authored-by: Jasper Furniss <[email protected]>
  • Loading branch information
nidaqg and jasperfurniss authored Nov 7, 2024
1 parent 64423a1 commit d13622a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ interface CustomCellProps {
onRowToggleClick?: (arg: Row<GenericObject>) => void
row: Row<GenericObject>
value?: string
customRenderer?: (row: Row<GenericObject>, value: string | undefined) => React.ReactNode
}

export const CustomCell = ({
getValue,
onRowToggleClick,
row,
value,
customRenderer,
}: CustomCellProps & GlobalProps) => {
const { setExpanded, expanded, expandedControl, inlineRowLoading } = useContext(AdvancedTableContext);

Expand Down Expand Up @@ -61,7 +63,12 @@ export const CustomCell = ({
</button>
) : null}
<FlexItem paddingLeft={renderButton? "none" : "xs"}>
{row.depth === 0 ? getValue() : value}
{row.depth === 0 ? (
customRenderer ? customRenderer(row, getValue()) : getValue()
) :(
customRenderer ? customRenderer(row, value) : value
)
}
</FlexItem>
</Flex>
</div>
Expand Down
49 changes: 21 additions & 28 deletions playbook/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ const AdvancedTable = (props: AdvancedTableProps) => {

const columnHelper = createColumnHelper()

//Create cells for first columns
const createCellFunction = (cellAccessors: string[], customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element) => {
//Create cells for columns, with customization for first column
const createCellFunction = (cellAccessors: string[], customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element, index?: number) => {
const columnCells = ({
row,
getValue,
Expand All @@ -101,19 +101,16 @@ const AdvancedTable = (props: AdvancedTableProps) => {
}) => {
const rowData = row.original

// Use customRenderer if provided, otherwise default rendering
if (customRenderer) {
return customRenderer(row, getValue())
}

if (index === 0) {
switch (row.depth) {
case 0: {
return (
<CustomCell
getValue={getValue}
onRowToggleClick={onRowToggleClick}
row={row}
/>
<CustomCell
customRenderer={customRenderer}
getValue={getValue}
onRowToggleClick={onRowToggleClick}
row={row}
/>
)
}
default: {
Expand All @@ -122,6 +119,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
const accessorValue = rowData[depthAccessor]
return accessorValue ? (
<CustomCell
customRenderer={customRenderer}
onRowToggleClick={onRowToggleClick}
row={row}
value={accessorValue}
Expand All @@ -132,11 +130,13 @@ const AdvancedTable = (props: AdvancedTableProps) => {
}
}
}

return customRenderer
? customRenderer(row, getValue())
: getValue()
}
return columnCells
}

//Create column array in format needed by Tanstack
//Create column array in format needed by Tanstack
const columns =
columnDefinitions &&
columnDefinitions.map((column, index) => {
Expand All @@ -147,19 +147,12 @@ const AdvancedTable = (props: AdvancedTableProps) => {
}),
}

// Use the custom renderer if provided, EXCEPT for the first column
if (index !== 0) {
if (column.cellAccessors || column.customRenderer) {
columnStructure.cell = createCellFunction(
column.cellAccessors,
column.customRenderer
)
}
} else {
// For the first column, apply createCellFunction without customRenderer
if (column.cellAccessors) {
columnStructure.cell = createCellFunction(column.cellAccessors)
}
if (column.cellAccessors || column.customRenderer) {
columnStructure.cell = createCellFunction(
column.cellAccessors,
column.customRenderer,
index
)
}

return columnStructure
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useState} from "react"
import { render, screen, waitFor } from "../utilities/test-utils"

import { AdvancedTable } from "playbook-ui"
import { AdvancedTable, Pill } from "playbook-ui"

const MOCK_DATA = [
{
Expand Down Expand Up @@ -88,6 +88,28 @@ const columnDefinitions = [
},
]

const columnDefinitionsCustomRenderer = [
{
accessor: "year",
label: "Year",
cellAccessors: ["quarter", "month", "day"],
},
{
accessor: "newEnrollments",
label: "New Enrollments",
customRenderer: (row, value) => (
<Pill text={value}
variant="success"
/>
),
},
{
accessor: "scheduledMeetings",
label: "Scheduled Meetings",
},
]


const subRowHeaders = ["Quarter"]

const testId = "advanced_table"
Expand Down Expand Up @@ -463,3 +485,17 @@ test("responsive none prop functions as expected", () => {
const kit = screen.getByTestId(testId)
expect(kit).toHaveClass("pb_advanced_table table-responsive-none")
})

test("customRenderer prop functions as expected", () => {
render(
<AdvancedTable
columnDefinitions={columnDefinitionsCustomRenderer}
data={{ testid: testId }}
tableData={MOCK_DATA}
/>
)

const kit = screen.getByTestId(testId)
const pill = kit.querySelector(".pb_pill_kit_success_lowercase")
expect(pill).toBeInTheDocument()
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react"
import { AdvancedTable, Pill, Body, Flex, Detail, Caption } from "playbook-ui"
import { AdvancedTable, Pill, Body, Flex, Detail, Caption, Badge, Title } from "playbook-ui"
import MOCK_DATA from "./advanced_table_mock_data.json"

const AdvancedTableCustomCell = (props) => {
Expand All @@ -8,7 +8,18 @@ const AdvancedTableCustomCell = (props) => {
accessor: "year",
label: "Year",
cellAccessors: ["quarter", "month", "day"],

customRenderer: (row, value) => (
<Flex>
<Title size={4}
text={value}
/>
<Badge dark
marginLeft="xxs"
text={row.original.newEnrollments > 20 ? "High" : "Low"}
variant="neutral"
/>
</Flex>
),
},
{
accessor: "newEnrollments",
Expand Down

0 comments on commit d13622a

Please sign in to comment.