아래로 반응 슬라이더(동적 높이)
21196 단어 styledcomponentshtmljavascriptreact
React, typescript, styled-components를 사용할 것입니다.
vite를 사용하여 앱을 만들었습니다.
먼저 DownSlider.tsx에 새 구성 요소를 만듭니다.
import React from "react";
import styled from "styled-components";
type DownSliderProps = {
expanded: boolean;
collapsedHeight: number;
expandedHeight: number;
};
// height doesn't animate, but max-height does
const Container = styled.div<DownSliderProps>`
position: relative;
background-color: beige;
overflow: hidden; // hide any overflowing content
${({ expanded, collapsedHeight, expandedHeight }) =>
expanded
? `max-height: ${expandedHeight}px; transition: max-height 0.5s;`
: `max-height: ${collapsedHeight}px; transition: max-height 0.5s;`}
`;
// ------------------------------------
// You can place the button inside or outside the content.
type Props = {
expanded: boolean;
collapsedHeight: number; // height of the button, if inside content
expandedHeight: number; // height of expanded content
children: React.ReactNode;
};
// ------------------------------------
const DownSlider = ({
expanded,
collapsedHeight,
expandedHeight,
children,
}: Props) => {
return (
<Container
expanded={expanded}
collapsedHeight={collapsedHeight}
expandedHeight={expandedHeight}
>
{children}
</Container>
);
};
export default DownSlider;
그런 다음 TestPage.tsx에서 슬라이더, 버튼, 일부 콘텐츠를 추가하고 일부 지연된 데이터 액세스를 시뮬레이션합니다.
import React, { useEffect, useRef, useState } from "react";
import styled from "styled-components";
import { DownSliderButton, DownSlider, Page } from "components";
const DownSliderContainer = styled.div`
width: 700px;
padding: 10px;
border-radius: 10px;
border: 1px solid forestgreen;
`;
const SlideTitle = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
background-color: #eee;
font-weight: bold;
`;
const SlideContent = styled.div`
padding: 10px;
`;
// ------------------------------------
const TestPage = () => {
const ref: any = useRef(null); // to measure content height
const initialHeight = 0; // 0: slides at start, ~1000: no sliding
const [updatedHeight, setUpdatedHeight] = useState(initialHeight);
const [isExpanded, setExpanded] = useState(true);
const [delayedData, setDelayedData] = useState("");
useEffect(() => {
setUpdatedHeight(ref.current?.clientHeight);
}, [ref.current?.clientHeight, delayedData]); // update triggers
useEffect(() => {
setTimeout(() => {
setDelayedData("This data arrives ~2s later.");
}, 2000);
}, []);
// ------------------------------------
return (
...
<DownSliderContainer>
<SlideTitle>
<div>Slide title</div>
<DownSliderButton isExpanded={isExpanded} setExpanded={setExpanded} />
</SlideTitle>
<DownSlider
expanded={isExpanded}
collapsedHeight={0}
expandedHeight={updatedHeight}
>
<SlideContent ref={ref}>
<div>Slide content</div>
<div>
<img
src={"/src/assets/cairn-terrier.jpg"}
alt="dog"
height={454}
/>
</div>
<div>More data arriving soon.</div>
<div>{delayedData}</div>
</SlideContent>
</DownSlider>
</DownSliderContainer>
...
);
};
export default TestPage;
완전성을 위해 다음은 DownSliderButton.tsx입니다.
import React from "react";
import styled from "styled-components";
// @ts-ignore
import { Rotator } from "components";
// @ts-ignore
import { CircleArrowRightIcon } from "svg";
const Container = styled.div`
cursor: pointer;
color: var(--color-primary-lighter);
& > div {
width: 32px;
height: 32px;
}
`;
// ------------------------------------
type Props = {
isExpanded: boolean;
setExpanded: (isExpanded: boolean) => void;
};
// ------------------------------------
const DownSliderButton = ({ isExpanded, setExpanded }: Props) => {
return (
<Container role="button" onClick={() => setExpanded(!isExpanded)}>
<Rotator rotated={isExpanded ? 90 : 180}>
<CircleArrowRightIcon />
</Rotator>
</Container>
);
};
export default DownSliderButton;
그리고 로테이터는 그 안에 배치한 모든 것을 회전시킵니다.
import styled, { css } from "styled-components";
type Props = {
rotated?: number;
};
const Rotator = styled.div<Props>`
transform: rotate(0deg);
transition: transform 0.5s ease-out;
${({ rotated }) =>
rotated !== undefined &&
css`
transform: rotate(${rotated}deg);
transition: transform 0.5s ease-out;
`};
`;
export default Rotator;
내 "svg/index.js"파일 내에서 이 버튼 구성 요소를 선언합니다.
export { ReactComponent as CircleArrowRightIcon } from "svg/circle-arrow-right.svg";
.. 이 svg를 가져옵니다.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentcolor">
<path d="M256 0C114.6 0 0 114.6 0 256c0 141.4 114.6 256 256 256s256-114.6 256-256C512 114.6 397.4 0 256 0zM406.6 278.6l-103.1 103.1c-12.5 12.5-32.75 12.5-45.25 0s-12.5-32.75 0-45.25L306.8 288H128C110.3 288 96 273.7 96 256s14.31-32 32-32h178.8l-49.38-49.38c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l103.1 103.1C414.6 241.3 416 251.1 416 256C416 260.9 414.6 270.7 406.6 278.6z"/>
</svg>
질문/의견, 알려주세요.
Reference
이 문제에 관하여(아래로 반응 슬라이더(동적 높이)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/elsyng/react-down-slider-dynamic-3loj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)