Skip to content

Commit

Permalink
feat(Table): add accordion row events (#1834)
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker authored Dec 20, 2022
1 parent dec1ddb commit c7be834
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
---
showTabs: true
---

## Events

No events are supported at the moment.
Events are a part of the accordion feature and needs to be enabled with the `accordion` property on the main Table.

| Events | Description |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `onClick` | _(optional)_ will emit when user clicks/expands the table row. Returns a native click. |
| `onOpened` | _(optional)_ Will emit when table row is expanded. Returns an object with the table row as the target: `{ target }`. |
| `onClosed` | _(optional)_ Will emit when table row is closed (after it was open). Returns an object with the table row as the target: `{ target }`. |
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,12 @@ import HeightAnimation, {
HeightAnimationProps,
} from '../HeightAnimation'
import HeightAnimationInstance from '../HeightAnimationInstance'
import {
testSetupInit,
simulateAnimationEnd,
} from './HeightAnimationUtils'

beforeEach(() => {
global.IS_TEST = false

window.requestAnimationFrame = jest.fn((callback) => {
return setTimeout(callback, 0)
})
window.cancelAnimationFrame = jest.fn((id) => {
clearTimeout(id)
return id
})
})
testSetupInit()

const getStates = () => {
const classes = document.querySelector(
Expand Down Expand Up @@ -444,10 +438,3 @@ describe('HeightAnimation', () => {
})
})
})

function simulateAnimationEnd(
element: Element = document.querySelector('.dnb-height-animation')
) {
const event = new CustomEvent('transitionend')
element.dispatchEvent(event)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export function testSetupInit() {
beforeEach(() => {
global.IS_TEST = false

window.requestAnimationFrame = jest.fn((callback) => {
return setTimeout(callback, 0)
})
window.cancelAnimationFrame = jest.fn((id) => {
clearTimeout(id)
return id
})
})
}

export function simulateAnimationEnd(
element: Element = document.querySelector('.dnb-height-animation')
) {
const event = new CustomEvent('transitionend')
element.dispatchEvent(event)
}
7 changes: 7 additions & 0 deletions packages/dnb-eufemia/src/components/table/TableAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export function useTableAccordion({
expanded,
disabled,
noAnimation,
onClick,
onOpened,
onClosed,
}) {
const tableContext = React.useContext(TableContext)

Expand Down Expand Up @@ -106,6 +109,8 @@ export function useTableAccordion({
noAnimation,
countTds,
hasAccordionContent,
onOpened,
onClosed,
}}
>
<tr
Expand Down Expand Up @@ -174,6 +179,8 @@ export function useTableAccordion({
) {
setOpen(!trIsOpen)
setHadClick(true)

onClick?.(event)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,30 @@ export default function TableAccordionContent(

const allProps = React.useContext(TableContext)?.allProps
const trContext = React.useContext(TrContext)
const innerRef = React.useRef(null)
const innerRef = React.useRef<HTMLDivElement>(null)
const trRef = React.useRef<HTMLTableRowElement>(null)
const [ariaLive, setAriaLive] = React.useState(null)

const { isInDOM, isAnimating, isVisibleParallax } = useHeightAnimation(
innerRef,
{
open: Boolean(expanded || trContext?.trIsOpen),
animate: Boolean(!noAnimation && !trContext?.noAnimation),
onOpen: (state) => setAriaLive(state ? true : null),
onOpen: (state) => {
setAriaLive(state ? true : null)
},
onAnimationEnd: (state) => {
const event = { target: trRef.current }
switch (state) {
case 'opened':
trContext.onOpened?.(event)
break

case 'closed':
trContext.onClosed?.(event)
break
}
},
}
)

Expand All @@ -72,6 +87,7 @@ export default function TableAccordionContent(
isVisibleParallax && 'dnb-table__tr__accordion_content--parallax',
className
)}
ref={trRef}
{...props}
>
<td
Expand Down
27 changes: 27 additions & 0 deletions packages/dnb-eufemia/src/components/table/TableTr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,43 @@ export type TableTrProps = {

/**
* Set true to render the tr initially as expanded
* Is part of the accordion feature and needs to be enabled with `accordion` prop in main Table
* Default: false
*/
expanded?: boolean

/**
* Set true to disable the tr to be accessible as an interactive element
* Is part of the accordion feature and needs to be enabled with `accordion` prop in main Table
* Default: false
*/
disabled?: boolean

/**
* Set to true to skip animation
* Is part of the accordion feature and needs to be enabled with `accordion` prop in main Table
* Default: false
*/
noAnimation?: boolean

/**
* Will emit when user clicks/expands the table row
* Is part of the accordion feature and needs to be enabled with `accordion` prop in main Table
*/
onClick?: (event?: React.SyntheticEvent) => void

/**
* Will emit when table row is expanded
* Is part of the accordion feature and needs to be enabled with `accordion` prop in main Table
*/
onOpened?: (event?: React.SyntheticEvent) => void

/**
* Will emit when table row is closed (after it was open)
* Is part of the accordion feature and needs to be enabled with `accordion` prop in main Table
*/
onClosed?: (event?: React.SyntheticEvent) => void

/**
* The content of the component.
*/
Expand All @@ -52,6 +73,9 @@ export default function Tr(
expanded,
disabled,
noAnimation,
onClick,
onOpened,
onClosed,
children,
className: _className,
...props
Expand All @@ -73,6 +97,9 @@ export default function Tr(
expanded,
disabled,
noAnimation,
onClick,
onOpened,
onClosed,
})

if (accordionTr) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import React from 'react'
import { render, fireEvent, createEvent } from '@testing-library/react'
import {
render,
fireEvent,
createEvent,
act,
} from '@testing-library/react'
import {
testSetupInit,
simulateAnimationEnd,
} from '../../height-animation/__tests__/HeightAnimationUtils'
import Table from '../Table'
import Tr from '../TableTr'
import Td from '../TableTd'
Expand Down Expand Up @@ -681,4 +690,100 @@ describe('TableAccordion', () => {
'dnb-table__tr__accordion_content--expanded'
)
})

describe('events', () => {
// Needed to "simulateAnimationEnd"
testSetupInit()

it('should emit onClick event', () => {
const onClick = jest.fn()
const trid = '123'

render(
<Table accordion>
<tbody>
<Tr onClick={onClick} data-trid={trid}>
<Td>content</Td>
<Td.AccordionContent>accordion content</Td.AccordionContent>
</Tr>
</tbody>
</Table>
)

const trElement = document.querySelector('tr')

fireEvent.click(trElement)

expect(onClick).toHaveBeenCalledTimes(1)

const { target } = onClick.mock.calls[0][0]
expect(target).toBe(trElement)
expect(target.dataset.trid).toBe(trid)
})

it('should emit onOpened event', async () => {
const onOpened = jest.fn()

render(
<Table accordion>
<tbody>
<Tr onOpened={onOpened}>
<Td>content</Td>
<Td.AccordionContent>accordion content</Td.AccordionContent>
</Tr>
</tbody>
</Table>
)

const trElement = document.querySelector('tr')

fireEvent.click(trElement)

act(() => {
simulateAnimationEnd(
document.querySelector(
'.dnb-table__tr__accordion_content__inner'
)
)

expect(onOpened).toHaveBeenCalledTimes(1)
expect(onOpened).toHaveBeenCalledWith({
target: expect.any(Element),
})
})
})

it('should emit onClosed event', async () => {
const onClosed = jest.fn()

render(
<Table accordion>
<tbody>
<Tr onClosed={onClosed}>
<Td>content</Td>
<Td.AccordionContent>accordion content</Td.AccordionContent>
</Tr>
</tbody>
</Table>
)

const trElement = document.querySelector('tr')

fireEvent.click(trElement)
fireEvent.click(trElement)

act(() => {
simulateAnimationEnd(
document.querySelector(
'.dnb-table__tr__accordion_content__inner'
)
)

expect(onClosed).toHaveBeenCalledTimes(1)
expect(onClosed).toHaveBeenCalledWith({
target: expect.any(Element),
})
})
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ const ContentTr = ({
expanded={expanded}
disabled={disabled}
// noAnimation
onClick={trClickHandler}
onOpened={trOpenHandler}
onClosed={trCloseHandler}
{...rest}
>
<Td>
Expand Down Expand Up @@ -517,6 +520,15 @@ const ContentTr = ({
</Tr>
)

function trClickHandler(event) {
console.log('trClickHandler', event)
}
function trOpenHandler(event) {
console.log('trOpenHandler', event)
}
function trCloseHandler(event) {
console.log('trCloseHandler', event)
}
function buttonClickHandler({ event }) {
event.preventDefault()
}
Expand Down

0 comments on commit c7be834

Please sign in to comment.