Skip to content

Commit

Permalink
feat(HeightAnimation): adjust height with animation when content changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker committed Sep 20, 2022
1 parent 72b1da5 commit 9aa2a0c
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,42 @@ export function HeightAnimationDefault() {
/* jsx */ `
const Example = () => {
const [openState, setOpenState] = React.useState(false)
const [contentState, setContentState] = React.useState(false)
const onChangeHandler = ({ checked }) => {
setOpenState(checked)
}
return (
<>
<ToggleButton checked={openState} onChange={onChangeHandler} bottom>
Toggle me
<ToggleButton
checked={openState}
onChange={({ checked }) => {
setOpenState(checked)
}}
>
Open/close
</ToggleButton>
<Section style_type="lavender">
<Section style_type="lavender" top>
<HeightAnimation
open={openState}
>
<P className="content-element" top="large" bottom="large">
Your content
</P>
<ToggleButton
checked={contentState}
onChange={({ checked }) => {
setContentState(checked)
}}
space={{ top: true, bottom: true }}
>
Change height as well
</ToggleButton>
{contentState && <P space={0}>Your content</P>}
</HeightAnimation>
</Section>
<P top>Look at me 👀</P>
</>
)
}
Expand All @@ -49,27 +65,41 @@ export function HeightAnimationKeepInDOM() {
{
/* jsx */ `
const Example = () => {
const [openState, setOpenState] = React.useState(false)
const [openState, setOpenState] = React.useState(true)
const [contentState, setContentState] = React.useState(false)
const onChangeHandler = ({ checked }) => {
setOpenState(checked)
}
return (
<>
<ToggleButton checked={openState} onChange={onChangeHandler} bottom>
Toggle me
<ToggleButton
checked={openState}
onChange={({ checked }) => {
setOpenState(checked)
}}
>
Open/close
</ToggleButton>
<StyledSection style_type="lavender">
<StyledSection style_type="lavender" top>
<HeightAnimation
open={openState}
keepInDOM={true}
duration={1000}
>
<P className="content-element" space={0}>
Your content
</P>
<ToggleButton
checked={contentState}
onChange={({ checked }) => {
setContentState(checked)
}}
space={{ top: true, bottom: true }}
>
Change height as well
</ToggleButton>
{contentState && <P space={0}>Your content</P>}
</HeightAnimation>
</StyledSection>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,12 @@ export default function HeightAnimation({
}: HeightAnimationProps & ISpacingProps) {
const ref = React.useRef<HTMLElement>()

const { isInDOM, isVisible, isVisibleParallax } = useHeightAnimation(
innerRef || ref,
{
const { isInDOM, isVisible, isVisibleParallax, isAnimating } =
useHeightAnimation(innerRef || ref, {
open,
animate,
}
)
children,
})

if (!isInDOM && !keepInDOM) {
return null
Expand All @@ -84,6 +83,7 @@ export default function HeightAnimation({
isInDOM && 'dnb-height-animation--is-in-dom',
isVisible && 'dnb-height-animation--is-visible',
isVisibleParallax && 'dnb-height-animation--parallax',
isAnimating && 'dnb-height-animation--animating',
className
)}
style={style}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ describe('HeightAnimation', () => {
open = false,
animate = true,
element = 'div',
children,
...props
}: Partial<HeightAnimationProps>) => {
const [openState, setOpenState] = React.useState(open)
Expand All @@ -58,7 +59,7 @@ describe('HeightAnimation', () => {
animate={animate} // Optional
{...props}
>
<p className="content-element">Your content</p>
<p className="content-element">Your content {children}</p>
</HeightAnimation>
</section>
</>
Expand Down Expand Up @@ -115,6 +116,50 @@ describe('HeightAnimation', () => {
})
})

it('should adjust height when content changes', async () => {
const { rerender } = render(<Component />)

expect(document.querySelector('.dnb-height-animation')).toBeFalsy()

rerender(<Component open />)

await act(async () => {
const element = document.querySelector('.dnb-height-animation')

simulateAnimationEnd()

expect(
document
.querySelector('.dnb-height-animation')
.getAttribute('style')
).toBe('height: auto;')

rerender(<Component open>123</Component>)

await wait(1)

expect(
document
.querySelector('.dnb-height-animation')
.getAttribute('style')
).toBe('height: 0px;')

jest
.spyOn(element, 'clientHeight', 'get')
.mockImplementationOnce(() => 100)

rerender(<Component open>456</Component>)

await wait(1)

expect(
document
.querySelector('.dnb-height-animation')
.getAttribute('style')
).toBe('height: 100px;')
})
})

it('should have content in DOM when keepInDOM is true', async () => {
const { rerender } = render(<Component keepInDOM />)

Expand Down Expand Up @@ -178,6 +223,7 @@ describe('HeightAnimation', () => {
'dnb-height-animation--is-in-dom',
'dnb-height-animation--is-visible',
'dnb-height-animation--parallax',
'dnb-height-animation--animating',
])

fireEvent.click(document.querySelector('button'))
Expand All @@ -187,6 +233,7 @@ describe('HeightAnimation', () => {
'dnb-height-animation',
'dnb-height-animation--is-in-dom',
'dnb-height-animation--is-visible',
'dnb-height-animation--animating',
])

simulateAnimationEnd()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,60 @@ import styled from '@emotion/styled'
import React from 'react'
import { P } from '../../../elements'
import Section from '../../section/Section'
import ToggleButton from '../../toggle-button/ToggleButton'
import { ToggleButton, Button } from '../../'
import HeightAnimation from '../HeightAnimation'

export default {
title: 'Eufemia/Components/HeightAnimation',
}

export const HeightAnimationSandbox = () => {
const [openState, setOpenState] = React.useState(false)

const onChangeHandler = ({ checked }) => {
setOpenState(checked)
}
const [count, setCount] = React.useState(0)
const [openState, setOpenState] = React.useState(true)
const [contentState, setContentState] = React.useState(false)

return (
<>
<ToggleButton checked={openState} onChange={onChangeHandler}>
Toggle me
<ToggleButton
checked={openState}
onChange={({ checked }) => {
setOpenState(checked)
}}
>
Open/close
</ToggleButton>

<StyledSection style_type="lavender">
<Button
onClick={() => {
setCount(count + 1)
}}
>
{count}
</Button>

<StyledSection style_type="lavender" top>
<HeightAnimation
open={openState}
element="div" // Optional
animate={true} // Optional
keepInDOM={true} // Optional
// duration={1000}
>
<P className="content-element" space={0}>
Your content
</P>
<ToggleButton
checked={contentState}
onChange={({ checked }) => {
setContentState(checked)
}}
space={{ top: true, bottom: true }}
>
Change height as well
</ToggleButton>

{contentState && <P>Your content</P>}
</HeightAnimation>
</StyledSection>

<P top>Look at me 👀</P>
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/

.dnb-height-animation {
overflow: hidden;
transition: height var(--duration, 400ms) var(--easing-default);

&--animating {
overflow: hidden;
}
}
Loading

0 comments on commit 9aa2a0c

Please sign in to comment.