AspectRatio
주어진 aspect-ratio 비율을 맞춰주기 위해 선언적으로 사용하는 유틸 컴포넌트입니다.
미리 영역을 확보하여 Layout Shift
를 방지하는데 효과적입니다.
다형성(polymorphism)
AspectRatio
컴포넌트는 다형성을 위해 as
속성을 지원합니다.
- 기본적으로
div
태그로 자식 요소를 감싸서 렌더링하며,as
속성을 통해 감싸는Wrapper
요소의 태그를 변경해 렌더링할 수 있습니다. (ex. div -> article) - 이때, 해당
Wrapper
요소에aspect-ratio
속성을 적용해 영역을 확보합니다.
합성(Composition), 렌더링 위임(Rendering Delegation)
AspectRatio
컴포넌트는 asChild
속성을 통해 합성(Composition)
, 렌더링 위임(Rendering Delegation)
패턴을 지원합니다.
asChild
속성이true
라면 Slot 을 통해 자식 요소를 렌더링합니다.- 이때, 자식 요소에
aspect-ratio
속성을 적용해 영역을 확보합니다.- Slot은 자식으로
단일 요소
만 허용됩니다. - Slot은 자식으로 컴포넌트가 올 경우
forwardRef
,props
를 허용해야 합니다. 허용하지 않으면 정상적으로 동작하지 않습니다. asChild
속성을 사용 할 경우 Slot 문서를 참고해주세요.
- Slot은 자식으로
Code
Interface
typescript
interface AspectRatioProps {
children: JSX.Element;
ratio: number;
asChild?: boolean;
style?: CSSProperties;
className?: string;
}
typescript
const AspectRatio: PolyForwardComponent<"div", AspectRatioProps, React.ElementType>
Usage
Default
- 기본적으로
div
요소에 감싸지며 해당div
에aspect-ratio
속성을 적용해 영역을 확보합니다.
typescript
import { AspectRatio } from '@modern-kit/react'
const Example = () => {
const imgUrl = 'https://github.com/user-attachments/assets/dd60ec12-afd7-44c9-bd6b-0069e16bf2c9';
return (
<div style={{ width: '500px' }}>
<AspectRatio ratio={427 / 640}>
<img src={imgUrl} />
</AspectRatio>
</div>
);
};
as
as
속성을 통해 감싸는 요소를div
가 아닌 특정 요소로 변경해 렌더링할 수 있으며, 해당 요소에aspect-ratio
속성을 적용해 영역을 확보합니다.
typescript
import { AspectRatio } from '@modern-kit/react'
const Example = () => {
const imgUrl = 'https://github.com/user-attachments/assets/dd60ec12-afd7-44c9-bd6b-0069e16bf2c9';
return (
<div style={{ width: '500px' }}>
<AspectRatio as="article" ratio={427 / 640}>
<img src={imgUrl} />
</AspectRatio>
</div>
);
};
asChild
asChild
속성이true
라면 Slot 을 통해 자식 요소를 그대로 렌더링하고, 자식 요소에aspect-ratio
속성을 적용해 영역을 확보합니다.
typescript
import { AspectRatio } from '@modern-kit/react'
const Example = () => {
const imgUrl = 'https://github.com/user-attachments/assets/dd60ec12-afd7-44c9-bd6b-0069e16bf2c9';
return (
<div style={{ width: '500px' }}>
<AspectRatio asChild ratio={427 / 640}>
<img src={imgUrl} style={{ width: '100%' }} />
</AspectRatio>
</div>
);
};