Skip to content

Commit f638e36

Browse files
authored
[New Component] Aspect Ratio component (#656)
1 parent a0efb52 commit f638e36

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use client';
2+
import React from 'react';
3+
import { customClassSwitcher } from '~/core';
4+
import { clsx } from 'clsx';
5+
const COMPONENT_NAME = 'AspectRatio';
6+
7+
export type AspectRatioProps = {
8+
children: React.ReactNode;
9+
customRootClass?: string;
10+
className?: string;
11+
ratio?: string;
12+
props: Record<string, any>[];
13+
}
14+
15+
const AspectRatio = ({ children, customRootClass, className, ratio="1", ...props }: AspectRatioProps) => {
16+
17+
if (isNaN(Number(ratio)) && !ratio.match(/^(\d+)\/(\d+)$/)) ratio = "1"
18+
if (Number(ratio) <= 0) ratio = "1"
19+
20+
const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME);
21+
return <div style={{aspectRatio:ratio}} className={clsx(rootClass, className)} {...props}>{children} </div>
22+
}
23+
AspectRatio.displayName = COMPONENT_NAME;
24+
25+
export default AspectRatio;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import AspectRatio from '../AspectRatio';
2+
import SandboxEditor from '~/components/tools/SandboxEditor/SandboxEditor';
3+
4+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
5+
export default {
6+
title: 'Components/AspectRatio',
7+
component: AspectRatio,
8+
render: (args) => <SandboxEditor>
9+
<AspectRatio {...args} >
10+
<img
11+
className="Image"
12+
src="https://images.pexels.com/photos/346529/pexels-photo-346529.jpeg?cs=srgb&dl=pexels-bri-schneiter-28802-346529.jpg&fm=jpg"
13+
alt="Landscape photograph"
14+
/>
15+
</AspectRatio>
16+
</SandboxEditor>
17+
};
18+
19+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
20+
export const Default = {
21+
args: {
22+
className:"",
23+
ratio: "16/9"
24+
}
25+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import { render, screen } from '@testing-library/react';
3+
import AspectRatio from '../AspectRatio';
4+
5+
describe('AspectRatio', () => {
6+
test('renders AspectRatio component', () => {
7+
render(<AspectRatio>Content</AspectRatio>);
8+
expect(screen.getByText('Content')).toBeInTheDocument();
9+
});
10+
11+
test('applies custom classes correctly', () => {
12+
render(<AspectRatio className="additional-class">Content</AspectRatio>);
13+
const divElement = screen.getByText('Content');
14+
expect(divElement).toHaveClass('additional-class');
15+
});
16+
17+
test('applies correct aspect ratio', () => {
18+
render(<AspectRatio ratio="16/9">Content</AspectRatio>);
19+
expect(screen.getByText('Content').style.aspectRatio).toBe('16/9');
20+
});
21+
22+
test('applies correct aspect ratio when ratio is not provided', () => {
23+
render(<AspectRatio >Content</AspectRatio>);
24+
expect(screen.getByText('Content').style.aspectRatio).toBe('1');
25+
});
26+
27+
test('applies correct aspect ratio when ratio is invalid', () => {
28+
render(<AspectRatio ratio="invalid">Content</AspectRatio>);
29+
expect(screen.getByText('Content').style.aspectRatio).toBe('1');
30+
});
31+
32+
test('applies correct aspect ratio when ratio contains a character', () => {
33+
render(<AspectRatio ratio="16/o">Content</AspectRatio>);
34+
expect(screen.getByText('Content').style.aspectRatio).toBe('1');
35+
});
36+
37+
test('applies correct aspect ratio when ratio is negative', () => {
38+
render(<AspectRatio ratio="-5">Content</AspectRatio>);
39+
expect(screen.getByText('Content').style.aspectRatio).toBe('1');
40+
});
41+
42+
43+
});

0 commit comments

Comments
 (0)