Skip to content

Commit

Permalink
Feat: Table footer in eds-core-react & eds-data-grid-react (#3624)
Browse files Browse the repository at this point in the history
* feat: add Table footer component to `eds-core-react`

- Implemented the Table footer component with optional sticky property for a fixed footer.
- Updated `Table.docs.mdx` to include documentation for the Table footer.
- Added Table footer to the storybook to showcase various use cases.
- Updated test suites to cover edge cases and ensure proper functionality of the Table footer.

* feat(eds-data-grid): add Table Footer component

feat(eds-data-grid): add Table Footer component

- Added the possibility to show a footer in the data grid.
- Enabled the option to make the footer fixed.
- Added `footerClass` and `footerStyle` as component props for custom styling.
- Updated docs and stories to include the new footer functionality.
- Updated test suites to cover edge cases and ensure proper functionality of the Table Footer.

chore: extract Resizer and TableCell components

-`Resizer` is now a separate module to enhance reusability and scalability.
- Renamed `Cell` to `TableCell` and moved it to a separate module for better reusability and scalability.
  • Loading branch information
zulu-eq-bouvet authored Sep 12, 2024
1 parent a5dca55 commit 5f8015c
Show file tree
Hide file tree
Showing 25 changed files with 1,276 additions and 75 deletions.
3 changes: 3 additions & 0 deletions packages/eds-core-react/src/components/Table/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TdHTMLAttributes, ThHTMLAttributes, forwardRef } from 'react'
import { Variants, Colors } from './Table.types'
import { TableDataCell } from './DataCell'
import { TableHeaderCell } from './HeaderCell'
import { TableFooterCell } from './FooterCell'
import { InnerContext } from './Inner.context'

export type CellProps = {
Expand All @@ -25,6 +26,8 @@ export const Cell = forwardRef<HTMLTableCellElement, CellProps>(function Cell(
switch (variant) {
case 'head':
return <TableHeaderCell ref={ref} sticky={sticky} {...rest} />
case 'foot':
return <TableFooterCell ref={ref} sticky={sticky} {...rest} />
default:
case 'body':
return <TableDataCell ref={ref} {...rest} />
Expand Down
26 changes: 26 additions & 0 deletions packages/eds-core-react/src/components/Table/Foot/Foot.tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { tokens } from '@equinor/eds-tokens'
import type { ComponentToken } from '@equinor/eds-tokens'

const {
colors: {
ui: {
background__medium: { rgba: borderColor },
},
interactive: {
table__header__fill_resting: { rgba: backgroundColor },
},
},
} = tokens

export const token: ComponentToken = {
background: backgroundColor,
border: {
type: 'bordergroup',
bottom: {
type: 'border',
width: '2px',
color: borderColor,
style: 'solid',
},
},
}
27 changes: 27 additions & 0 deletions packages/eds-core-react/src/components/Table/Foot/Foot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { HTMLAttributes, forwardRef } from 'react'
import styled from 'styled-components'
import { token } from './Foot.tokens'
import { bordersTemplate } from '@equinor/eds-utils'
import { InnerContext } from '../Inner.context'

const StyledTableFoot = styled.tfoot`
${bordersTemplate(token.border)}
background: ${token.background};
`

export type FootProps = {
/** Footer will stick to bottom when scrolling */
sticky?: boolean
} & HTMLAttributes<HTMLTableSectionElement>

export const Foot = forwardRef<HTMLTableSectionElement, FootProps>(
function Foot({ children, sticky, ...props }, ref) {
return (
<InnerContext.Provider value={{ variant: 'foot', sticky }}>
<StyledTableFoot {...props} ref={ref}>
{children}
</StyledTableFoot>
</InnerContext.Provider>
)
},
)
1 change: 1 addition & 0 deletions packages/eds-core-react/src/components/Table/Foot/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Foot'
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { ThHTMLAttributes, forwardRef } from 'react'
import styled, { css, ThemeProvider } from 'styled-components'
import {
typographyTemplate,
spacingsTemplate,
bordersTemplate,
useToken,
} from '@equinor/eds-utils'
import {
token as tableFoot,
TableHeadToken as TableFootToken,
} from './../HeaderCell/HeaderCell.tokens' // Use Header cell tokens as default
import { useEds } from '../../EdsProvider'

type BaseProps = {
theme: TableFootToken
$sticky: boolean
}

const StyledTableCell = styled.th((props: BaseProps) => {
const { theme, $sticky } = props
const { background, height, typography, spacings } = theme

return css`
min-height: ${height};
height: ${height};
background: ${background};
box-sizing: border-box;
${spacingsTemplate(spacings)}
${typographyTemplate(typography)}
${bordersTemplate(theme.border)}
${$sticky
? css`
position: sticky;
bottom: 0;
z-index: 2;
`
: ''}
`
})

const CellInner = styled.div`
display: flex;
align-items: center;
`

type CellProps = {
sticky?: boolean
} & ThHTMLAttributes<HTMLTableCellElement>

export const TableFooterCell = forwardRef<HTMLTableCellElement, CellProps>(
function TableFooterCell({ children, sticky, ...rest }, ref) {
const { density } = useEds()
const token = useToken({ density }, tableFoot)
const props = {
ref,
$sticky: sticky,
...rest,
}

return (
<ThemeProvider theme={token}>
<StyledTableCell {...props}>
<CellInner>{children}</CellInner>
</StyledTableCell>
</ThemeProvider>
)
},
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './FooterCell'
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { createContext } from 'react'

type State = {
variant: 'body' | 'head'
variant: 'body' | 'head' | 'foot'
sticky?: boolean
}

const initalState: State = {
const initialState: State = {
variant: 'body',
}

export const InnerContext = createContext<State>(initalState)
export const InnerContext = createContext<State>(initialState)
24 changes: 24 additions & 0 deletions packages/eds-core-react/src/components/Table/Table.docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ Tables display information in an easy to scan format.
<li>Icons can be used for sorting columns as well as a alternative text.</li>
</ul>


**Table Footer**
<ul>
<li>The table footer is used to display summary information, totals, or additional notes that relate to the data presented in the table body.</li>
<li> It serves as the concluding section of the table, often providing context or aggregated data that complements the table's content.</li>
<li>The width of footer cells is customizable using the `colSpan` prop, allowing footer cells to span multiple columns. This is useful for displaying summary data or totals that need to align visually across the table.</li>
</ul>


**Table Cell**
<ul>
<li>The cell row can have icons, text, links, inputs, numbers, monospaced numbers and other custom content (by using the placeholder).</li>
Expand Down Expand Up @@ -80,13 +89,24 @@ const Demo = () => {
<Table.Cell>2.5</Table.Cell>
</Table.Row>
</Table.Body>
<Table.Foot>
<Table.Row>
<Table.Cell colspan={3}>Footer</Table.Cell>
</Table.Row>
</Table.Foot>
</Table>
)
}
```

## Examples

### Fixed Table Header & Footer

<Canvas of={ComponentStories.FixedTableHeaderAndFooter} />



### Fixed table header

<Canvas of={ComponentStories.FixedTableHeader} />
Expand All @@ -108,3 +128,7 @@ To render very large datasets, "virtual scrolling" might sometimes be a good opt
combination with 3rd party solutions such as <a href="https://tanstack.com/virtual/v3">react-virtual</a> to achieve this.

<Canvas of={ComponentStories.VirtualScrolling} />


### Virtual scrolling with fixed footer
<Canvas of={ComponentStories.VirtualScrollingWithFixedFooter} />
Loading

0 comments on commit 5f8015c

Please sign in to comment.