Starting mix-height
angelod1as opened this issue · 7 comments
I'm trying to achieve the following:
In order to do that, I should have a min-height
property, and collapse should work from that. Eg: it will set height as 500px
when collapsed, and full when no collapsed.
When clicking Veja mais
, it should toggle isOpened
(I already set that up using useState
)
Is setting this "half-collapsed" style possible?
Make your own container 500px tall, then on click - height auto.
Wrap it with Collapse (always opened + css transitions as standard).
It will work! Collapse would just follow content height with animation.
Following what you said:
import { ReactNode, useCallback, useState } from 'react'
import { StyledMosaic, SeeMore, Wrapper } from './styles'
import { Collapse } from 'react-collapse'
interface MosaicProps {
children: ReactNode
limit: boolean
}
export default function Mosaic({ children, limit }: MosaicProps) {
const [isOpened, setIsOpened] = useState(false) // Handles Collapse
const [height, setHeight] = useState('500px') // Handles height changes
const handleClick = useCallback(() => {
setHeight('auto')
setIsOpened(!isOpened)
}, [isOpened])
return (
<Wrapper>
<Collapse isOpened={isOpened}> // Wraps div with 500px height initially
<StyledMosaic height={height}>{children}</StyledMosaic> // changes height from 500px to auto on click
</Collapse>
{limit ? (
<SeeMore onClick={handleClick}>
{isOpened ? 'Veja menos' : 'Veja mais'}
</SeeMore>
) : (
''
)}
</Wrapper>
)
}
I use Styled Components to do CSS:
import styled from 'styled-components'
export const Wrapper = styled.div`
position: relative;
.ReactCollapse--collapse {
transition: height 0.7s;
}
`
export const StyledMosaic = styled.div<{ height: string }>`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
align-items: center;
justify-content: center;
grid-gap: 20px;
transition: max-height 0.3s;
height: ${p => p.height};
`
export const SeeMore = styled.div`
[ommited]
`
The result isn't what you described. It's like this collapsed:
And, when clicking the Veja mais
button, it opens properly, without issue.
Sure, should've tried with less variables.
Sadly, it still doesn't work or I'm still getting things wrong.
Below you can see the simplified code. No Styled Components or grid
.
It's a simple component. The Collapse
is opened by watching the state (it starts closed). It's height is initalized as 500
, so it should work as described.
Above the Collapse
component, a simple button handles click, that in time changes height
to auto
and toggles isOpened
.
I even disabled animation to see if it would work, and it doesn't.
export default function Mosaic({ children }) {
const [isOpened, setIsOpened] = useState(false)
const [height, setHeight] = useState<number | string>(500)
const handleClick = useCallback(() => {
setHeight('auto')
setIsOpened(!isOpened)
}, [isOpened])
return (
<div>
<button onClick={handleClick}>
{isOpened ? 'Veja menos' : 'Veja mais'}
</button>
<Collapse isOpened={isOpened}>
<div style={{ height: height }}>{children}</div>
</Collapse>
</div>
)
}
Collapsed:
Opened (image cropped for clarity):
I also tried without {children}
, with simple divs with text inside, and it still doesn't work.
you need to make sure collapse is always opened
<Collapse isOpened={true}>
<div style={{ height: height }}>{children}</div>
</Collapse>
GOT IT! Styled Components were messing with the updating height.
For reference, the working code is like this:
export default function Mosaic({ children }) {
const [height, setHeight] = useState<number | string>(500)
const handleClick = useCallback(() => {
setHeight(height === 500 ? 'auto' : 500)
}, [height])
return (
<Wrapper>
<Collapse isOpened={true}>
<div
style={{ height: height, overflow: 'hidden', position: 'relative' }}
>
<StyledMosaic>{children}</StyledMosaic>
</div>
</Collapse>
<SeeMore onClick={handleClick}>
{height === 500 ? 'Veja mais' : 'Veja menos'}
</SeeMore>
</Wrapper>
)
}
this div
that holds the StyledMosaic
is what does the magic.
OOF, @nkbt , thanks a lot for the help. I'm happily closing this issue <3
Awesome! Glad it worked out.