Skip to content

Commit 38892b1

Browse files
committed
feat: add Collapse
1 parent 816c1f2 commit 38892b1

File tree

5 files changed

+103
-70
lines changed

5 files changed

+103
-70
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Collapse } from '@solved-ac/ui-react'
2+
import { ComponentMeta, ComponentStory } from '@storybook/react'
3+
import React from 'react'
4+
5+
export default {
6+
title: 'Collapse',
7+
component: Collapse,
8+
argTypes: {
9+
shown: {
10+
control: 'boolean',
11+
description: 'Whether the children should be shown',
12+
},
13+
},
14+
} as ComponentMeta<typeof Collapse>
15+
16+
const Template: ComponentStory<typeof Collapse> = (args) => (
17+
<Collapse {...args} />
18+
)
19+
20+
export const Default = Template.bind({})
21+
Default.args = {
22+
children: (
23+
<>
24+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec
25+
vulputate arcu, nec semper est. Vestibulum ante ipsum primis in faucibus
26+
orci luctus et ultrices posuere cubilia curae; Suspendisse vel purus et
27+
metus laoreet efficitur in ut elit. Duis ultrices enim dapibus purus
28+
imperdiet molestie. Nam pretium odio metus, tempus vehicula neque sodales
29+
quis. Suspendisse vehicula, libero ac viverra consectetur, ante lectus
30+
malesuada ex, ut porta nunc justo quis neque. Aenean tristique nulla quis
31+
eros faucibus, sit amet lacinia nibh interdum. Quisque aliquet leo ut erat
32+
ultrices posuere. Duis mauris nulla, posuere sed dapibus eget, ultricies
33+
id dui. Phasellus vel augue a urna fermentum vehicula. Quisque sed elit
34+
non nibh ullamcorper lacinia. Orci varius natoque penatibus et magnis dis
35+
parturient montes, nascetur ridiculus mus. Duis nibh ligula, scelerisque
36+
porta rutrum ac, tempus vitae ipsum. Morbi ut ante a felis fringilla
37+
aliquam bibendum nec felis. Donec vel nunc congue, rhoncus mauris quis,
38+
malesuada nisi.
39+
</>
40+
),
41+
}

example/yarn-error.log

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/components/Collapse.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { ReactHTML, useLayoutEffect, useRef, useState } from 'react'
2+
3+
export interface CollapseProps {
4+
shown: boolean
5+
as?: keyof ReactHTML
6+
}
7+
8+
export const Collapse: React.FC<CollapseProps> = (props) => {
9+
const { as, shown, children } = props
10+
11+
const contentsRef = useRef<HTMLDivElement>(null)
12+
const [contentHeight, setContentHeight] = useState<number>(0)
13+
const [renderHeight, setRenderHeight] = useState<number | 'auto'>(0)
14+
const [mountChild, setMountChild] = useState<boolean>(shown)
15+
const [prevShown, setPrevShown] = useState<boolean>(shown)
16+
17+
useLayoutEffect(() => {
18+
if (contentsRef.current === null || !mountChild) return
19+
setContentHeight(contentsRef.current?.clientHeight ?? 0)
20+
}, [children, mountChild])
21+
22+
useLayoutEffect(() => {
23+
if (shown) setMountChild(true)
24+
25+
setRenderHeight(shown ? 0 : contentHeight)
26+
const renderHeightDelay = setTimeout(() => {
27+
setRenderHeight(shown ? contentHeight : 0)
28+
}, 30)
29+
const animationDelay = setTimeout(() => {
30+
setPrevShown(shown)
31+
setRenderHeight(shown ? 'auto' : 0)
32+
if (!shown) setMountChild(false)
33+
}, 400)
34+
return () => {
35+
clearTimeout(renderHeightDelay)
36+
clearTimeout(animationDelay)
37+
}
38+
}, [shown, contentHeight])
39+
40+
const RenderComponent = as ?? 'div'
41+
42+
return (
43+
<RenderComponent
44+
style={{
45+
height: renderHeight,
46+
transformOrigin: 'top',
47+
opacity: prevShown || shown ? 1 : 0,
48+
transition: `height .3s ease, opacity .3s ease`,
49+
pointerEvents: prevShown || shown ? 'all' : 'none',
50+
overflow: 'hidden',
51+
}}
52+
>
53+
{mountChild ? <div ref={contentsRef}>{children}</div> : null}
54+
</RenderComponent>
55+
)
56+
}
57+
58+
Collapse.defaultProps = {
59+
as: 'div',
60+
}

src/components/Space.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22

3-
interface SpaceProps {
3+
export interface SpaceProps {
44
h?: number | string
55
w?: number | string
66
}

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './Button'
2+
export * from './Collapse'
23
export * from './Space'
34

0 commit comments

Comments
 (0)