Skip to content

Commit

Permalink
feat(Tr): automate odd/even and make it overridable (#1705)
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker authored Nov 7, 2022
1 parent 3f678bd commit d73d3cb
Show file tree
Hide file tree
Showing 3 changed files with 391 additions and 6 deletions.
18 changes: 13 additions & 5 deletions packages/dnb-eufemia/src/components/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,19 @@ const Table = (
const { elementRef } = useStickyHeader(allProps)

// Create this ref in order to "auto" set even/odd class in tr elements
const trTmpRef = React.useRef({ count: 0 })
React.useLayoutEffect(() => {
trTmpRef.current.count = 0
})
const trCountRef = React.useRef({ count: 0 })

// When the alias changes, all tr's will rerender and get a new even/odd color
// This is usefull, when one tr gets removed
const [rerenderAlias, setRerenderAlias] = React.useState({}) // eslint-disable-line no-unused-vars

validateDOMAttributes(allProps, props)

return (
<Provider skeleton={Boolean(skeleton)}>
<TableContext.Provider value={{ trTmpRef }}>
<TableContext.Provider
value={{ trCountRef, rerenderAlias, forceRerender }}
>
<table
className={classnames(
'dnb-table',
Expand All @@ -121,6 +124,11 @@ const Table = (
</TableContext.Provider>
</Provider>
)

function forceRerender() {
trCountRef.current.count = 0
setRerenderAlias({})
}
}

export default Table
Expand Down
92 changes: 91 additions & 1 deletion packages/dnb-eufemia/src/components/table/TableTr.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react'
import classnames from 'classnames'
import { TableTdProps } from './TableTd'
import TableContext from './TableContext'

export type TableTrProps = {
/**
* The variant of the tr
*/
variant?: 'even' | 'odd'

/**
* The content of the component.
*/
Expand All @@ -22,17 +28,101 @@ const Tr = (
React.TableHTMLAttributes<HTMLTableRowElement>
) => {
const {
variant,
className,
children,

...props
} = componentProps

const tableContext = React.useContext(TableContext)

const { currentVariant, trRef, trParams } = useHandleTrLogic({
tableContext,
variant,
})

return (
<tr className={classnames('dnb-table__tr', className)} {...props}>
<tr
role="row"
className={classnames(
'dnb-table__tr',
currentVariant && `dnb-table__tr--${currentVariant}`,
className
)}
ref={trRef}
{...trParams}
{...props}
>
{children}
</tr>
)
}

export default Tr

function useHandleTrLogic({ tableContext, variant }) {
const trRef = React.useRef(null)

/**
* Handle odd/even
*/
const countRef = tableContext?.trCountRef.current
const increment = () => {
if (typeof countRef === 'undefined') {
return 0
}
if (
!variant ||
(variant === 'even' && countRef.count % 2 === 1) ||
(variant === 'odd' && countRef.count % 2 === 0)
) {
countRef.count++
}

return countRef.count
}
const decrement = () => {
if (typeof countRef === 'undefined') {
return null
}
if (
!variant ||
(variant === 'even' && countRef.count % 2 === 1) ||
(variant === 'odd' && countRef.count % 2 === 0)
) {
countRef.count--
tableContext?.forceRerender()
}
}

// Run increment during SSR
const count = React.useMemo(increment, [tableContext?.rerenderAlias]) // eslint-disable-line react-hooks/exhaustive-deps

// Run decrement when component unmounts and force the whole table to re-render
React.useEffect(() => decrement, [tableContext?.trCountRef]) // eslint-disable-line react-hooks/exhaustive-deps

// For the whole table to re-render when a variant changes
React.useEffect(() => {
tableContext?.forceRerender()
}, [variant]) // eslint-disable-line react-hooks/exhaustive-deps

/**
* Find out the current odd/even when "accordionContent" is used.
* Because we have now an additional "tr" element.
* Then the CSS can't figure out the correct nth element (nth-of-type)
* and we need to set it manually (nth-child and nth-of-type do not respect classes, so we can't ignore this one).
*/
let currentVariant = variant
if (!currentVariant) {
currentVariant = count % 2 ? 'odd' : 'even'
}

const trParams = {}

return {
trRef,
currentVariant,
trParams,
}
}
Loading

0 comments on commit d73d3cb

Please sign in to comment.