-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(grid): create grid component (#118)
* feat(grid): grid component - Added a new Grid component with customizable grid properties - Implemented GridItem for individual grid items - Created Storybook stories for visual testing and documentation - Added unit tests using Vitest to ensure functionality and style application * refactor(grid): improve Grid component props and structure BREAKING CHANGE: Remove sipe-team/card dependency and restructure Grid props - Remove redundant grid props that are already supported - Add new GridItem props (colSpan, rowSpan, colStart, colEnd, rowStart, rowEnd) - Remove sipe-team/card library dependency - Enhance test coverage for new GridItem props - Add comprehensive Grid stories demonstrating new features * chore: update pnpm-lock.yaml * Create unlucky-rice-grab.md * chore: update pnpm-lock * refactor(grid): optimize with default values and memoization - Add useMemo for memoizing grid column and row calculations - Provide sensible default values for Grid and GridItem props --------- Co-authored-by: y09n <[email protected]>
- Loading branch information
1 parent
04c2635
commit 08121f0
Showing
32 changed files
with
1,544 additions
and
1,034 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@sipe-team/grid": minor | ||
--- | ||
|
||
feat(grid): create grid component |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,22 @@ | ||
.avatar { | ||
width: var(--avatar-size); | ||
height: var(--avatar-size); | ||
border-radius: var(--avatar-shape); | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
overflow: hidden; | ||
background-color: #e2e8f0; | ||
width: var(--avatar-size); | ||
height: var(--avatar-size); | ||
border-radius: var(--avatar-shape); | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
overflow: hidden; | ||
background-color: #e2e8f0; | ||
} | ||
|
||
.image { | ||
width: 100%; | ||
height: 100%; | ||
object-fit: cover; | ||
width: 100%; | ||
height: 100%; | ||
object-fit: cover; | ||
} | ||
|
||
.fallback { | ||
font-size: 0.8rem; | ||
color: #2d3748; | ||
text-align: center; | ||
font-size: 0.8rem; | ||
color: #2d3748; | ||
text-align: center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,60 @@ | ||
import { faker } from "@faker-js/faker"; | ||
import { render, screen } from "@testing-library/react"; | ||
import { expect, test, describe, it } from "vitest"; | ||
import { Avatar } from "./Avatar"; | ||
import type { AvatarShape, AvatarSize } from "./Avatar"; | ||
import { faker } from '@faker-js/faker'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { expect, test, describe, it } from 'vitest'; | ||
import { Avatar } from './Avatar'; | ||
import type { AvatarShape, AvatarSize } from './Avatar'; | ||
|
||
const testImage = faker.image.avatar(); | ||
|
||
test("Avatar 컴포넌트가 주입받은 이미지 주소를 src 속성으로 설정한다.", () => { | ||
test('Avatar 컴포넌트가 주입받은 이미지 주소를 src 속성으로 설정한다.', () => { | ||
render(<Avatar src={testImage} alt="대체 텍스트" />); | ||
|
||
const img = screen.getByRole("img"); | ||
expect(img).toHaveAttribute("src", testImage); | ||
const img = screen.getByRole('img'); | ||
expect(img).toHaveAttribute('src', testImage); | ||
}); | ||
|
||
test("이미지가 없을 경우 대체 텍스트를 표시한다.", () => { | ||
test('이미지가 없을 경우 대체 텍스트를 표시한다.', () => { | ||
render(<Avatar alt="대체 텍스트" />); | ||
|
||
expect(screen.getByText("대체 텍스트")).toBeInTheDocument(); | ||
expect(screen.getByText('대체 텍스트')).toBeInTheDocument(); | ||
}); | ||
|
||
test("이미지 로드 실패 시 fallback을 표시한다.", () => { | ||
render( | ||
<Avatar | ||
src="broken-link" | ||
fallback="https://randomuser.me/api/portraits/women/1.jpg" | ||
/> | ||
); | ||
test('이미지 로드 실패 시 fallback을 표시한다.', () => { | ||
render(<Avatar src="broken-link" fallback="https://randomuser.me/api/portraits/women/1.jpg" />); | ||
|
||
const img = screen.getByRole("img"); | ||
img.dispatchEvent(new Event("error")); | ||
const img = screen.getByRole('img'); | ||
img.dispatchEvent(new Event('error')); | ||
|
||
expect(img).toHaveAttribute( | ||
"src", | ||
"https://randomuser.me/api/portraits/women/1.jpg" | ||
); | ||
expect(img).toHaveAttribute('src', 'https://randomuser.me/api/portraits/women/1.jpg'); | ||
}); | ||
|
||
describe("Avatar 컴포넌트", () => { | ||
describe('Avatar 컴포넌트', () => { | ||
const sizes: { size: AvatarSize; expectedSize: string }[] = [ | ||
{ size: "xs", expectedSize: "24px" }, | ||
{ size: "sm", expectedSize: "32px" }, | ||
{ size: "md", expectedSize: "40px" }, | ||
{ size: "lg", expectedSize: "70px" }, | ||
{ size: "xl", expectedSize: "96px" }, | ||
{ size: 'xs', expectedSize: '24px' }, | ||
{ size: 'sm', expectedSize: '32px' }, | ||
{ size: 'md', expectedSize: '40px' }, | ||
{ size: 'lg', expectedSize: '70px' }, | ||
{ size: 'xl', expectedSize: '96px' }, | ||
]; | ||
|
||
const shapes: { shape: AvatarShape; expectedRadius: string }[] = [ | ||
{ shape: "circle", expectedRadius: "50%" }, | ||
{ shape: "rounded", expectedRadius: "4px" }, | ||
{ shape: "square", expectedRadius: "0px" }, | ||
{ shape: 'circle', expectedRadius: '50%' }, | ||
{ shape: 'rounded', expectedRadius: '4px' }, | ||
{ shape: 'square', expectedRadius: '0px' }, | ||
]; | ||
|
||
it.each(sizes)( | ||
"size가 $size일때 $expectedSize x $expectedSize 크기로 렌더링 된다.", | ||
({ size, expectedSize }) => { | ||
render(<Avatar src={testImage} size={size} />); | ||
const container = screen.getByRole("img").parentElement; | ||
expect(container).toHaveStyle({ | ||
width: expectedSize, | ||
height: expectedSize, | ||
}); | ||
} | ||
); | ||
|
||
it.each(shapes)( | ||
"shape가 $shape일때 borderRadius는 $expectedRadius로 나타난다.", | ||
({ shape, expectedRadius }) => { | ||
render(<Avatar src={testImage} shape={shape} />); | ||
const container = screen.getByRole("img").parentElement; | ||
expect(container).toHaveStyle({ borderRadius: expectedRadius }); | ||
} | ||
); | ||
it.each(sizes)('size가 $size일때 $expectedSize x $expectedSize 크기로 렌더링 된다.', ({ size, expectedSize }) => { | ||
render(<Avatar src={testImage} size={size} />); | ||
const container = screen.getByRole('img').parentElement; | ||
expect(container).toHaveStyle({ | ||
width: expectedSize, | ||
height: expectedSize, | ||
}); | ||
}); | ||
|
||
it.each(shapes)('shape가 $shape일때 borderRadius는 $expectedRadius로 나타난다.', ({ shape, expectedRadius }) => { | ||
render(<Avatar src={testImage} shape={shape} />); | ||
const container = screen.getByRole('img').parentElement; | ||
expect(container).toHaveStyle({ borderRadius: expectedRadius }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { StorybookConfig } from '@storybook/react-vite'; | ||
|
||
export default { | ||
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], | ||
addons: [ | ||
'@storybook/addon-onboarding', | ||
'@storybook/addon-links', | ||
'@storybook/addon-essentials', | ||
'@storybook/addon-interactions', | ||
], | ||
framework: { | ||
name: '@storybook/react-vite', | ||
options: {}, | ||
}, | ||
} satisfies StorybookConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { Preview } from '@storybook/react'; | ||
|
||
export default { | ||
tags: ['autodocs'], | ||
} satisfies Preview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
declare module '*.module.css'; |
Oops, something went wrong.