Skip to content

Commit ac21245

Browse files
committed
[9] Реализовать сложный компонент
Реализован компонент "Сворачивание" (Collapse)
1 parent bab705b commit ac21245

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.collapse-container {
2+
border: 1px solid #ccc;
3+
border-radius: 4px;
4+
margin: 10px 0;
5+
overflow: hidden;
6+
}
7+
8+
.collapse-button {
9+
width: 100%;
10+
background-color: #007bff;
11+
color: white;
12+
padding: 10px;
13+
border: none;
14+
cursor: pointer;
15+
text-align: left;
16+
font-size: 1em;
17+
18+
&:hover {
19+
background-color: #0056b3;
20+
}
21+
}
22+
23+
.collapse-content {
24+
padding: 10px;
25+
background-color: #f9f9f9;
26+
transition: height 0.3s ease;
27+
}

src/shared/collapse/Collapse.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React, { useState, useRef, useEffect, ReactNode } from 'react';
2+
import s from './Collapse.module.scss';
3+
4+
type CollapseProps = {
5+
title: string;
6+
children: ReactNode;
7+
};
8+
9+
export const Collapse = ({ title, children }: CollapseProps) => {
10+
const [isOpen, setIsOpen] = useState(false);
11+
const [height, setHeight] = useState(0);
12+
const contentRef = useRef<HTMLDivElement>(null);
13+
14+
const toggleCollapse = () => {
15+
setIsOpen(!isOpen);
16+
};
17+
18+
useEffect(() => {
19+
const resizeObserver = new ResizeObserver((entries) =>
20+
entries.forEach((entry) => setHeight(entry.borderBoxSize[0].blockSize))
21+
);
22+
23+
const currentContentRef = contentRef.current;
24+
25+
currentContentRef && resizeObserver.observe(currentContentRef);
26+
27+
return () => {
28+
currentContentRef && resizeObserver.unobserve(currentContentRef);
29+
};
30+
}, []);
31+
32+
return (
33+
<div className={s['collapse-container']}>
34+
<button className={s['collapse-button']} onClick={toggleCollapse}>
35+
{title}
36+
</button>
37+
<div
38+
style={{
39+
height: `${isOpen ? height : 0}px`,
40+
overflow: 'hidden',
41+
transition: 'height 300ms ease',
42+
}}
43+
>
44+
<div ref={contentRef} className={s['collapse-content']}>
45+
{children}
46+
</div>
47+
</div>
48+
</div>
49+
);
50+
};

src/stories/Collapse.stories.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import type { Meta } from '@storybook/react';
3+
4+
import { Collapse } from '../shared/collapse/Collapse';
5+
import { Button } from '../shared/button/Button';
6+
7+
const meta: Meta<typeof Collapse> = {
8+
component: Collapse,
9+
title: 'Сложные компоненты/Сворачивание',
10+
tags: ['autodocs'],
11+
};
12+
13+
export default meta;
14+
15+
export const Test = {
16+
args: {
17+
title: 'Сворачиваемый контент',
18+
children: (
19+
<>
20+
<Button>Some button</Button>
21+
<p>
22+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Incidunt, perferendis! Non autem consectetur amet
23+
sint at saepe veniam doloremque, culpa dolore corporis ad consequuntur temporibus? Magni laudantium eum dolor
24+
tempora.
25+
</p>
26+
</>
27+
),
28+
},
29+
};

0 commit comments

Comments
 (0)