Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(avatar): avatar 컴포넌트 구현 #45

Merged
merged 19 commits into from
Jan 9, 2025
Merged

feat(avatar): avatar 컴포넌트 구현 #45

merged 19 commits into from
Jan 9, 2025

Conversation

kimdaeyeobbb
Copy link
Contributor

@kimdaeyeobbb kimdaeyeobbb commented Dec 3, 2024

변경사항

  • Avatar #21

  • 기능 명세를 만족하는 테스트 시나리오 작성 a16e7e1

  • 테스트 시나리오를 만족하도록 컴포넌트의 기능 구현 0608c10

  • 스토리 작성 c66f5b6

시각자료

image

체크리스트

  • 기능 명세를 작성하였나요?
  • 테스트 코드를 작성하였나요?

추가 논의사항

Summary by CodeRabbit

릴리스 노트

  • 신규 기능

    • 아바타 컴포넌트를 위한 새로운 Storybook 구성 추가.
    • 다양한 크기와 모양의 아바타를 시각화할 수 있는 스토리 추가.
    • 아바타 컴포넌트에 대한 단위 테스트 추가.
    • 아바타 컴포넌트의 새로운 TypeScript 구성 파일 및 빌드 설정 추가.
    • 새로운 CSS 모듈을 통한 아바타 스타일 정의.
    • 새로운 패키지 @sipe-team/avatar 추가.
    • CSS 모듈을 인식할 수 있는 TypeScript 선언 추가.
  • 버그 수정

    • 이미지 로드 실패 시 대체 이미지를 표시하는 기능 개선.
  • 문서화

    • Storybook 및 테스트 환경을 위한 구성 파일 추가.

Copy link

changeset-bot bot commented Dec 3, 2024

⚠️ No Changeset found

Latest commit: cce1e51

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment on lines 2 to 3
"name": "@sipe-team/component",
"description": "component for Sipe Design System",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 이름이 안 바껴있어요!


type Story = StoryObj<typeof meta>;

const testImage = faker.image.avatar();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위클리 때 들었던 faker 야무지게 사용하셨네요 👍

Comment on lines 31 to 39
test('기본 크기는 40px이다.', () => {
render(<Avatar src={testImage} />);
expect(screen.getByRole('img')).toHaveStyle({ width: '40px', height: '40px' });
});

test('원형 형태로 표시한다.', () => {
render(<Avatar src={testImage} shape="circle" />);
expect(screen.getByRole('img')).toHaveStyle({ borderRadius: '50%' });
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 크기나 shape도 잘 되는지 확인하는 코드가 있으면 좋겠네요

@noahluftyang noahluftyang linked an issue Dec 7, 2024 that may be closed by this pull request
const testImage = faker.image.avatar();


test('이미지를 정상적으로 표시한다.', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정상적이라는 단어가 조금 주관적인 표현이라고 생각해~ 이렇게 다듬어보면 어떨까?
=> 주입받은 이미지 주소를 src로 설정한다.


const img = screen.getByRole('img');
expect(img).toHaveAttribute('src', testImage);
expect(img).toHaveAttribute('alt', '대체 텍스트');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alt attribute를 확인하는건 이 테스트의 역할이 아니기도 하고, 바로 아래 테스트에서 검증하고 있기 때문에 이 구문은 지워도 될 것 같아!

Comment on lines 33 to 60
const style = {
'--avatar-size': getAvatarSize(size),
'--avatar-shape': getAvatarShape(shape),
} as CSSProperties;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prop으로 주입 받은 style도 그대로 넘겨주도록 작성하면 어떨까?

@developerjhp
Copy link
Member

토끼야 리뷰해줘
@coderabbitai review

Copy link

coderabbitai bot commented Dec 7, 2024

@developerjhp: 변경 사항을 검토하겠습니다.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

coderabbitai bot commented Dec 7, 2024

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/avatar/.storybook/main.ts

Oops! Something went wrong! :(

ESLint: 9.17.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

Walkthrough

이 변경 사항은 @sipe-team/avatar 패키지의 Storybook 구성 및 Avatar 컴포넌트를 위한 여러 파일을 도입합니다. 새로운 TypeScript 파일들이 추가되어 Storybook의 기본 설정과 프리뷰 설정을 정의하고, CSS 모듈이 생성되어 컴포넌트 스타일을 지정합니다. 또한, Avatar 컴포넌트와 관련된 스토리, 테스트 및 구성 파일들이 포함되어 있어, 전반적으로 패키지의 구조와 기능성을 향상시킵니다.

Changes

파일 경로 변경 요약
packages/avatar/.storybook/main.ts Storybook의 기본 설정을 정의하는 새 구성 파일 추가.
packages/avatar/.storybook/preview.ts Storybook 프리뷰 설정을 위한 새로운 TypeScript 파일 추가.
packages/avatar/package.json 새로운 package.json 파일 추가, 메타데이터 및 스크립트 정의 포함.
packages/avatar/src/Avatar.module.css Avatar 컴포넌트를 위한 CSS 모듈 추가, 스타일 클래스 정의.
packages/avatar/src/Avatar.stories.tsx Avatar 컴포넌트에 대한 Storybook 스토리 구성 추가.
packages/avatar/src/Avatar.test.tsx Avatar 컴포넌트에 대한 단위 테스트 추가.
packages/avatar/src/Avatar.tsx Avatar 컴포넌트 및 AvatarProps 인터페이스 추가.
packages/avatar/src/index.ts Avatar.tsx에서 모든 엔티티를 내보내는 export 추가.
packages/avatar/tsconfig.json TypeScript 구성 파일 추가, 기본 설정 상속.
packages/avatar/tsup.config.ts tsup 빌드 구성 파일 추가, 빌드 설정 정의.
packages/avatar/vitest.config.ts Vitest 테스트 환경을 설정하는 구성 파일 추가.
packages/avatar/vitest.setup.ts @testing-library/jest-dom 패키지 임포트 추가, DOM 관련 매처 제공.
packages/avatar/global.d.ts CSS 모듈을 가져올 수 있도록 TypeScript 정의 추가.

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • bae-sh
  • heeji289
  • synuns
  • developerjhp
  • froggy1014
  • noahluftyang

Poem

🐰 새로운 구성과 함께
아바타가 빛나네!
스토리북 속에서
다양한 모습으로
친구들과 함께
즐거운 시간을 보내요!

Finishing Touches

  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (9)
packages/avatar/vitest.setup.ts (1)

1-4: 테스트 설정이 적절히 구성되었습니다.

DOM 테스트를 위한 필수적인 설정이 잘 되어있습니다. 다만, 타입스크립트 환경에서의 더 나은 개발 경험을 위해 다음과 같은 개선사항을 제안드립니다.

타입 정의를 위해 다음과 같이 수정해보세요:

+/// <reference types="@testing-library/jest-dom" />
 import '@testing-library/jest-dom';

이렇게 하면 IDE에서 matcher들의 타입 힌트를 더 정확하게 제공받을 수 있습니다.

packages/avatar/vitest.config.ts (2)

4-14: 테스트 환경 설정이 적절합니다만, 몇 가지 고려사항이 있습니다.

환경 설정이 잘 되어 있으나, 다음 사항들을 고려해보시기 바랍니다:

  • happy-domjsdom 중 선택한 이유를 문서화하면 좋을 것 같습니다
  • 글로벌 API 사용 시 타입 지원을 위한 추가 설정이 필요할 수 있습니다

다음과 같이 주석을 보강하는 것을 제안드립니다:

   test: {
-    // 테스트를 실행할 환경
-    // default: 'node'
-    // 브라우저 환경에서 테스트를 희망시 - 'jsdom' 또는 'happy-dom'으로 설정
+    // 테스트를 실행할 환경
+    // default: 'node'
+    // happy-dom 선택 이유: jsdom보다 가벼우며 컴포넌트 테스트에 충분한 기능 제공
     environment: 'happy-dom',

23-26: 플러그인 관련 추가 고려사항이 있습니다.

현재 플러그인이 비어있는데, 다음 플러그인들의 추가를 고려해보시면 좋을 것 같습니다:

  • vite-tsconfig-paths: TypeScript 경로 별칭 지원
  • @vitejs/plugin-react: React 관련 기능 지원

다음과 같은 변경을 제안드립니다:

   // 환경별로 설정해주어야하는 추가 기능을 플러그인으로 주입 가능
   // ex) vite-tsconfig-paths
-  plugins: [],
+  plugins: [
+    // TypeScript 경로 별칭을 지원하기 위한 플러그인
+    tsconfigPaths(),
+    // React 지원을 위한 플러그인
+    react(),
+  ],
packages/avatar/src/Avatar.test.tsx (1)

8-14: 테스트 설명을 더 명확하게 개선해 주세요.

"정상적으로"라는 표현이 다소 모호합니다. 테스트의 목적을 더 구체적으로 설명하는 것이 좋겠습니다.

다음과 같이 변경을 제안합니다:

-test('이미지를 정상적으로 표시한다.', () => {
+test('주입받은 이미지 주소를 src 속성에 설정한다.', () => {
packages/avatar/src/Avatar.stories.tsx (2)

19-24: Basic 스토리의 이미지 소스를 일관되게 변경해 주세요.

다른 스토리들은 faker를 사용하는데 Basic 스토리만 하드코딩된 URL을 사용하고 있습니다.

다음과 같이 변경을 제안합니다:

export const Basic: Story = {
  args: {
-   src: 'https://randomuser.me/api/portraits/men/1.jpg',
+   src: testImage,
    alt: '대체 텍스트',
  },
};

29-34: alt 텍스트 포맷을 일관되게 맞춰주세요.

크기를 나타내는 alt 텍스트가 "XSmall"과 "small" 등 일관성이 없습니다.

다음과 같이 변경을 제안합니다:

-        <Avatar size="xs" src={testImage} alt="XSmall" />
-        <Avatar size="sm" src={testImage}  alt="small" />
-        <Avatar size="md" src={testImage}  alt="medium" />
-        <Avatar size="lg" src={testImage} alt="large" />
-        <Avatar size="xl" src={testImage} alt="XLarge" />
+        <Avatar size="xs" src={testImage} alt="아주 작은 크기" />
+        <Avatar size="sm" src={testImage} alt="작은 크기" />
+        <Avatar size="md" src={testImage} alt="중간 크기" />
+        <Avatar size="lg" src={testImage} alt="큰 크기" />
+        <Avatar size="xl" src={testImage} alt="아주 큰 크기" />
packages/avatar/package.json (1)

24-25: 워크스페이스 의존성의 버전 지정자가 일관적이지 않습니다

@sipe-team/typography는 "*"를, @sipe-team/tokens는 "^"를 사용하고 있습니다. 워크스페이스 패키지들은 동일한 버전 지정자를 사용하는 것이 좋습니다.

-    "@sipe-team/typography": "workspace:*",
-    "@sipe-team/tokens": "workspace:^",
+    "@sipe-team/typography": "workspace:^",
+    "@sipe-team/tokens": "workspace:^",
packages/avatar/src/Avatar.tsx (2)

44-46: 에러 처리 로직을 개선할 수 있습니다

현재 에러 처리가 fallback이 있을 때만 동작합니다. fallback이 없는 경우에도 적절한 처리가 필요할 수 있습니다.

    onError={(e) => {
-     if (fallback) e.currentTarget.src = fallback;
+     if (fallback) {
+       e.currentTarget.src = fallback;
+     } else {
+       e.currentTarget.style.display = 'none';
+     }
    }}

9-16: props에 대한 JSDoc 문서화가 필요합니다

각 prop의 용도와 가능한 값들에 대한 설명을 JSDoc으로 추가하면 좋겠습니다.

+/**
+ * Avatar 컴포넌트의 props 인터페이스
+ */
 export interface AvatarProps extends ComponentProps<'div'> {
+  /** 다른 컴포넌트로 렌더링할지 여부 */
   asChild?: boolean;
+  /** 아바타 이미지 소스 URL */
   src?: string;
+  /** 이미지 대체 텍스트 */
   alt?: string;
+  /** 아바타 크기 ('xs' | 'sm' | 'md' | 'lg' | 'xl') */
   size?: AvatarSize;
+  /** 아바타 모양 ('circle' | 'rounded' | 'square') */
   shape?: AvatarShape;
+  /** 이미지 로드 실패시 표시할 대체 이미지 URL */
   fallback?: string;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 80f5a5b and c66f5b6.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • packages/avatar/.storybook/main.ts (1 hunks)
  • packages/avatar/.storybook/preview.ts (1 hunks)
  • packages/avatar/package.json (1 hunks)
  • packages/avatar/src/Avatar.module.css (1 hunks)
  • packages/avatar/src/Avatar.stories.tsx (1 hunks)
  • packages/avatar/src/Avatar.test.tsx (1 hunks)
  • packages/avatar/src/Avatar.tsx (1 hunks)
  • packages/avatar/src/index.ts (1 hunks)
  • packages/avatar/tsconfig.json (1 hunks)
  • packages/avatar/tsup.config.ts (1 hunks)
  • packages/avatar/vitest.config.ts (1 hunks)
  • packages/avatar/vitest.setup.ts (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • packages/avatar/tsconfig.json
  • packages/avatar/src/index.ts
  • packages/avatar/tsup.config.ts
  • packages/avatar/src/Avatar.module.css
  • packages/avatar/.storybook/preview.ts
🔇 Additional comments (5)
packages/avatar/vitest.config.ts (2)

1-3: LGTM! 기본 구성이 잘 되어있습니다.

vitest/config에서 defineConfig를 가져와서 적절하게 사용하고 있습니다.


15-21: 설정 파일의 존재 여부를 확인해주세요.

setupFiles에 지정된 vitest.setup.ts 파일이 올바른 위치에 존재하는지 확인이 필요합니다.

✅ Verification successful

설정 파일이 정상적으로 존재합니다.

packages/avatar/vitest.setup.ts 파일이 지정된 위치에서 확인되었습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence of vitest.setup.ts file
# Expected: File should exist in the same directory as vitest.config.ts

# Find the setup file
fd -p "packages/avatar/vitest.setup.ts"

Length of output: 71

packages/avatar/.storybook/main.ts (1)

1-16: 설정이 잘 구성되어 있습니다! ✨

필수적인 Storybook 애드온들이 모두 포함되어 있고, TypeScript 타입 체크도 적절히 적용되어 있습니다.

packages/avatar/package.json (1)

2-2: ⚠️ Potential issue

패키지 이름이 컴포넌트의 특성을 반영하지 않습니다

현재 패키지 이름이 "@sipe-team/component"로 되어있는데, 이는 너무 일반적입니다. Avatar 컴포넌트를 위한 패키지이므로 "@sipe-team/avatar"로 변경하는 것이 좋겠습니다.

packages/avatar/src/Avatar.tsx (1)

33-36: 🛠️ Refactor suggestion

스타일 props 처리 개선이 필요합니다

사용자가 전달한 style prop과 내부 스타일을 병합하도록 수정하면 좋겠습니다.

  const style = {
+   ...props.style,
    '--avatar-size': getAvatarSize(size),
    '--avatar-shape': getAvatarShape(shape),
  } as CSSProperties;

Comment on lines 31 to 39
test('기본 크기는 40px이다.', () => {
render(<Avatar src={testImage} />);
expect(screen.getByRole('img')).toHaveStyle({ width: '40px', height: '40px' });
});

test('원형 형태로 표시한다.', () => {
render(<Avatar src={testImage} shape="circle" />);
expect(screen.getByRole('img')).toHaveStyle({ borderRadius: '50%' });
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

테스트 케이스를 보완해 주세요.

크기와 모양에 대한 테스트가 기본값만 확인하고 있습니다. 다양한 크기와 모양 조합에 대한 테스트 케이스를 추가하면 좋겠습니다.

다음과 같은 테스트 케이스 추가를 제안합니다:

test.each([
  ['xs', '24px'],
  ['sm', '32px'],
  ['md', '40px'],
  ['lg', '48px'],
  ['xl', '56px'],
])('size가 %s일 때 %s 크기로 렌더링된다', (size, expected) => {
  render(<Avatar src={testImage} size={size} />);
  expect(screen.getByRole('img')).toHaveStyle({ 
    width: expected, 
    height: expected 
  });
});

test.each(['circle', 'rounded', 'square'])
('shape가 %s일 때 올바른 스타일이 적용된다', (shape) => {
  render(<Avatar src={testImage} shape={shape} />);
  const img = screen.getByRole('img');
  if (shape === 'circle') {
    expect(img).toHaveStyle({ borderRadius: '50%' });
  } else if (shape === 'rounded') {
    expect(img).toHaveStyle({ borderRadius: '8px' });
  } else {
    expect(img).toHaveStyle({ borderRadius: '0px' });
  }
});

"@storybook/test": "catalog:",
"@types/react": "^18.3.12",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.0.1",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

@testing-library/react 버전이 최신이 아닙니다

현재 "@testing-library/react"의 버전이 ^16.0.1로 설정되어 있습니다. 최신 안정 버전을 사용하는 것이 좋습니다.

-    "@testing-library/react":  "^16.0.1",
+    "@testing-library/react":  "^14.1.2",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@testing-library/react": "^16.0.1",
"@testing-library/react": "^14.1.2",

fallback,
...props
}: AvatarProps,
ref: ForwardedRef<any>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

ref 타입이 너무 광범위합니다

ForwardedRef<any> 대신 더 구체적인 타입을 사용하는 것이 좋습니다. HTMLDivElement 또는 HTMLElement를 사용하여 타입 안전성을 높일 수 있습니다.

-    ref: ForwardedRef<any>
+    ref: ForwardedRef<HTMLDivElement>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ref: ForwardedRef<any>
ref: ForwardedRef<HTMLDivElement>

@noahluftyang noahluftyang enabled auto-merge (squash) December 28, 2024 12:13
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/avatar/src/Avatar.tsx (4)

11-12: 타입 정의에 JSDoc 문서를 추가하면 좋겠습니다

타입 정의에 각 값이 어떤 의미를 가지는지 설명하는 JSDoc 문서를 추가하면 컴포넌트 사용자가 더 쉽게 이해할 수 있습니다.

+/** Avatar 컴포넌트의 크기를 정의합니다. */
 type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
+/** Avatar 컴포넌트의 모서리 형태를 정의합니다. */
 type AvatarShape = "circle" | "rounded" | "square";

14-21: 프로퍼티 설명을 추가해주세요

각 프로퍼티의 용도와 기능을 설명하는 JSDoc 문서를 추가하면 좋겠습니다.

 export interface AvatarProps extends ComponentProps<"div"> {
+  /** Radix UI의 Slot을 사용하여 다른 엘리먼트로 렌더링할지 여부 */
   asChild?: boolean;
+  /** 아바타 이미지의 URL */
   src?: string;
+  /** 이미지의 대체 텍스트 */
   alt?: string;
+  /** 아바타의 크기 */
   size?: AvatarSize;
+  /** 아바타의 모서리 형태 */
   shape?: AvatarShape;
+  /** 이미지 로드 실패시 표시할 대체 이미지 URL */
   fallback?: string;
 }

54-56: 이미지 에러 처리 로직을 개선해주세요

현재 구현은 fallback이 있을 때만 에러를 처리합니다. 에러 발생 시 로깅이나 사용자 피드백을 추가하는 것이 좋겠습니다.

 onError={(e) => {
+  console.warn('Avatar 이미지 로드 실패:', src);
   if (fallback) e.currentTarget.src = fallback;
+  else {
+    // fallback이 없을 경우 alt 텍스트를 보여주기 위해 이미지를 제거
+    e.currentTarget.style.display = 'none';
+  }
 }}

66-92: 유틸리티 함수를 별도 파일로 분리하는 것이 좋겠습니다

getAvatarSizegetAvatarShape 함수를 별도의 유틸리티 파일로 분리하면 코드 구조가 더 깔끔해지고 재사용성이 향상됩니다.

새로운 파일 utils.ts를 생성하여 다음과 같이 분리하는 것을 제안합니다:

// utils.ts
export function getAvatarSize(size: AvatarSize) {
  // ... 현재 구현 ...
}

export function getAvatarShape(shape: AvatarShape) {
  // ... 현재 구현 ...
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb4a394 and 2c8f934.

📒 Files selected for processing (2)
  • packages/avatar/src/Avatar.test.tsx (1 hunks)
  • packages/avatar/src/Avatar.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/avatar/src/Avatar.test.tsx
🔇 Additional comments (1)
packages/avatar/src/Avatar.tsx (1)

34-34: ref 타입이 너무 광범위합니다

ForwardedRef<any> 대신 더 구체적인 타입을 사용하는 것이 좋습니다.

-  ref: ForwardedRef<any>
+  ref: ForwardedRef<HTMLDivElement>

Comment on lines 38 to 60
const style = {
"--avatar-size": size,
"--avatar-shape": shape,
} as CSSProperties;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

style 프로퍼티 전달 방식 개선이 필요합니다

현재 구현은 커스텀 CSS 변수만 설정하고 있습니다. 사용자가 전달한 style 프로퍼티와 병합하여 처리해야 합니다.

 const style = {
+  ...props.style,
   "--avatar-size": size,
   "--avatar-shape": shape,
 } as CSSProperties;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const style = {
"--avatar-size": size,
"--avatar-shape": shape,
} as CSSProperties;
const style = {
...props.style,
"--avatar-size": size,
"--avatar-shape": shape,
} as CSSProperties;

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/avatar/src/Avatar.tsx (2)

11-12: 타입 정의에 JSDoc 문서화 추가 필요

AvatarSizeAvatarShape 타입에 대한 JSDoc 문서화를 추가하여 각 옵션값의 의미와 사용 사례를 명확히 설명하는 것이 좋습니다.

+/**
+ * Avatar 컴포넌트의 크기 옵션
+ * @type {AvatarSize}
+ * - xs: 24px
+ * - sm: 32px
+ * - md: 40px (기본값)
+ * - lg: 70px
+ * - xl: 96px
+ */
 type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
+
+/**
+ * Avatar 컴포넌트의 모양 옵션
+ * @type {AvatarShape}
+ * - circle: 원형 (50% border-radius)
+ * - rounded: 둥근 모서리 (4px border-radius)
+ * - square: 정사각형 (0px border-radius)
+ */
 type AvatarShape = 'circle' | 'rounded' | 'square';

66-92: 상수값 분리 및 오류 처리 개선 필요

크기와 모양에 대한 상수값을 별도의 상수/테마 파일로 분리하고, 잘못된 값이 전달되었을 때의 오류 처리를 추가하는 것이 좋습니다.

다음과 같이 개선할 수 있습니다:

  1. 상수 파일 생성 (constants.ts):
export const AVATAR_SIZES = {
  xs: '24px',
  sm: '32px',
  md: '40px',
  lg: '70px',
  xl: '96px',
} as const;

export const AVATAR_SHAPES = {
  rounded: '4px',
  square: '0px',
  circle: '50%',
} as const;
  1. 함수 개선:
import { AVATAR_SIZES, AVATAR_SHAPES } from './constants';

function getAvatarSize(size: AvatarSize): string {
  if (!(size in AVATAR_SIZES)) {
    console.warn(`Invalid avatar size: ${size}. Falling back to 'md'`);
    return AVATAR_SIZES.md;
  }
  return AVATAR_SIZES[size];
}

function getAvatarShape(shape: AvatarShape): string {
  if (!(shape in AVATAR_SHAPES)) {
    console.warn(`Invalid avatar shape: ${shape}. Falling back to 'circle'`);
    return AVATAR_SHAPES.circle;
  }
  return AVATAR_SHAPES[shape];
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c8f934 and 54b3a92.

📒 Files selected for processing (3)
  • packages/avatar/package.json (1 hunks)
  • packages/avatar/src/Avatar.test.tsx (1 hunks)
  • packages/avatar/src/Avatar.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/avatar/src/Avatar.test.tsx
  • packages/avatar/package.json
🔇 Additional comments (2)
packages/avatar/src/Avatar.tsx (2)

34-34: ref 타입이 너무 광범위합니다

ForwardedRef<any> 대신 더 구체적인 타입을 사용하는 것이 좋습니다. HTMLDivElement 또는 HTMLElement를 사용하여 타입 안전성을 높일 수 있습니다.


38-41: style 프로퍼티 전달 방식 개선이 필요합니다

현재 구현은 커스텀 CSS 변수만 설정하고 있습니다. 사용자가 전달한 style 프로퍼티와 병합하여 처리해야 합니다.

Comment on lines +50 to +80
{src ? (
<img
src={src}
alt={alt}
onError={(e) => {
if (fallback) e.currentTarget.src = fallback;
}}
className={styles.image}
/>
) : (
<span className={styles.fallback}>{alt || fallback}</span>
)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

접근성 개선이 필요합니다

이미지 로딩 실패 시 스크린 리더 사용자에게 적절한 피드백을 제공해야 합니다.

 {src ? (
   <img
     src={src}
     alt={alt}
+    aria-invalid={false}
     onError={(e) => {
-      if (fallback) e.currentTarget.src = fallback;
+      if (fallback) {
+        e.currentTarget.src = fallback;
+        e.currentTarget.setAttribute('aria-invalid', 'true');
+      }
     }}
     className={styles.image}
   />
 ) : (
-  <span className={styles.fallback}>{alt || fallback}</span>
+  <span className={styles.fallback} role="img" aria-label={alt || fallback}>
+    {alt || fallback}
+  </span>
 )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{src ? (
<img
src={src}
alt={alt}
onError={(e) => {
if (fallback) e.currentTarget.src = fallback;
}}
className={styles.image}
/>
) : (
<span className={styles.fallback}>{alt || fallback}</span>
)}
{src ? (
<img
src={src}
alt={alt}
aria-invalid={false}
onError={(e) => {
if (fallback) {
e.currentTarget.src = fallback;
e.currentTarget.setAttribute('aria-invalid', 'true');
}
}}
className={styles.image}
/>
) : (
<span className={styles.fallback} role="img" aria-label={alt || fallback}>
{alt || fallback}
</span>
)}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54b3a92 and ca9b196.

📒 Files selected for processing (1)
  • packages/avatar/package.json (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: chromatic
🔇 Additional comments (6)
packages/avatar/package.json (6)

13-21: 스크립트 구성이 잘 되어있습니다!

빌드, 테스트, 타입 체크 등 필요한 스크립트들이 모두 잘 구성되어 있습니다.


22-27: 의존성 설정이 적절합니다!

내부 패키지는 workspace 의존성을 사용하고, 외부 패키지는 적절한 버전으로 고정되어 있습니다.


40-40: @testing-library/react 버전이 최신이 아닙니다

현재 "@testing-library/react"의 버전이 ^16.0.1로 설정되어 있습니다. 최신 안정 버전을 사용하는 것이 좋습니다.

-    "@testing-library/react": "^16.0.1",
+    "@testing-library/react": "^14.1.2",

48-50: Peer 의존성이 적절하게 설정되었습니다!

React 18 이상을 요구하는 것이 적절합니다.


51-66: 배포 설정이 잘 되어있습니다!

ESM과 CommonJS 모듈 형식을 모두 지원하도록 잘 구성되어 있습니다.


67-67: 사이드 이펙트 설정이 적절합니다!

UI 컴포넌트 패키지에 적합한 설정입니다.

Comment on lines 2 to 9
"name": "@sipe-team/component",
"description": "Avatar component for Sipe Design System",
"version": "0.0.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/sipe-team/3-1_sds"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

패키지 이름과 저장소 URL을 수정해주세요

  1. 패키지 이름이 너무 일반적입니다. Avatar 컴포넌트를 위한 패키지이므로 더 구체적인 이름을 사용하는 것이 좋습니다.
  2. 저장소 URL이 현재 PR의 저장소와 일치하지 않습니다.
-  "name": "@sipe-team/component",
+  "name": "@sipe-team/avatar",
   ...
-    "url": "https://github.com/sipe-team/3-1_sds"
+    "url": "https://github.com/sipe-team/3-2_side"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"name": "@sipe-team/component",
"description": "Avatar component for Sipe Design System",
"version": "0.0.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/sipe-team/3-1_sds"
},
"name": "@sipe-team/avatar",
"description": "Avatar component for Sipe Design System",
"version": "0.0.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/sipe-team/3-2_side"
},

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
packages/avatar/package.json (2)

2-2: ⚠️ Potential issue

패키지 이름과 저장소 URL이 올바르지 않습니다

  1. 패키지 이름이 Avatar 컴포넌트의 목적과 맞지 않습니다
  2. 저장소 URL이 현재 PR의 저장소와 다릅니다
-  "name": "@sipe-team/component",
+  "name": "@sipe-team/avatar",
   ...
-    "url": "https://github.com/sipe-team/3-1_sds"
+    "url": "https://github.com/sipe-team/3-2_side"

Also applies to: 8-8

🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated


42-42: ⚠️ Potential issue

@testing-library/react 버전을 업데이트해주세요

현재 16.0.1 버전을 사용 중이나, 최신 안정 버전은 14.1.2입니다.

-    "@testing-library/react": "^16.0.1",
+    "@testing-library/react": "^14.1.2",
🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🧹 Nitpick comments (1)
packages/avatar/package.json (1)

15-23: 코드 포맷팅 스크립트가 누락되었습니다

Biome을 사용하고 있지만 format 스크립트가 정의되어 있지 않습니다. 일관된 코드 스타일을 위해 format 스크립트를 추가해주세요.

   "scripts": {
     "build": "tsup",
     "build:storybook": "storybook build",
     "dev:storybook": "storybook dev -p 6006",
     "lint": "biome lint .",
+    "format": "biome format .",
     "test": "vitest",
     "typecheck": "tsc",
     "prepack": "pnpm run build"
   }
🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eaf683d and cf0be64.

📒 Files selected for processing (1)
  • packages/avatar/package.json (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Chromatic
packages/avatar/package.json

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI
packages/avatar/package.json

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage
packages/avatar/package.json

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🔇 Additional comments (2)
packages/avatar/package.json (2)

53-68: 배포 설정이 잘 구성되어 있습니다

ESM과 CJS 모듈 형식을 모두 지원하도록 올바르게 설정되어 있습니다.

🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated


69-69: 트리 쉐이킹 최적화가 올바르게 설정되어 있습니다

sideEffects: false 설정으로 번들 크기 최적화가 가능합니다.

🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

Comment on lines 24 to 51
"dependencies": {
"@radix-ui/react-slot": "^1.1.0",
"@sipe-team/typography": "workspace:^",
"@sipe-team/tokens": "workspace:*",
"clsx": "^2.1.1"
},
"devDependencies": {
"@biomejs/biome": "catalog:",
"@faker-js/faker": "^9.2.0",
"@storybook/addon-essentials": "catalog:",
"@storybook/addon-interactions": "catalog:",
"@storybook/addon-links": "catalog:",
"@storybook/blocks": "catalog:",
"@storybook/react": "catalog:",
"@storybook/react-vite": "catalog:",
"@storybook/test": "catalog:",
"@types/react": "^18.3.12",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.0.1",
"happy-dom": "catalog:",
"react": "^18.3.1",
"storybook": "catalog:",
"tsup": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
},
"peerDependencies": {
"react": ">= 18"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

pnpm-lock.yaml 파일을 업데이트해주세요

CI 파이프라인에서 package.json과 lockfile이 일치하지 않는다는 오류가 발생했습니다. 다음 명령어를 실행하여 lockfile을 업데이트해주세요:

pnpm install
🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

"url": "https://github.com/sipe-team/3-1_sds"
},
"type": "module",
"exports": "./src/index.ts",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

exports 필드가 소스 파일을 직접 가리키고 있습니다

배포된 패키지는 컴파일된 파일을 가리켜야 합니다. src 대신 dist 디렉토리를 참조하도록 수정해주세요.

-  "exports": "./src/index.ts",
+  "exports": {
+    ".": {
+      "import": "./dist/index.js",
+      "require": "./dist/index.cjs",
+      "types": "./dist/index.d.ts"
+    }
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"exports": "./src/index.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
}
🧰 Tools
🪛 GitHub Actions: Chromatic

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: CI

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

🪛 GitHub Actions: Run tests and upload coverage

[error] Package dependency specifications in package.json do not match the lockfile (pnpm-lock.yaml). Lock file needs to be updated

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/avatar/package.json (1)

26-27: 워크스페이스 의존성 버전 지정자를 통일해주세요

워크스페이스 의존성의 버전 지정자가 일관되지 않습니다 (^ vs *).

다음과 같이 통일해주세요:

-    "@sipe-team/typography": "workspace:^",
-    "@sipe-team/tokens": "workspace:*",
+    "@sipe-team/typography": "workspace:*",
+    "@sipe-team/tokens": "workspace:*",
packages/avatar/src/Avatar.tsx (1)

85-111: 크기와 모양 관련 상수를 분리하여 관리하면 좋을 것 같습니다

크기와 모양 값을 상수로 분리하면 유지보수성이 향상되고, 재사용성이 높아집니다.

다음과 같이 수정해주세요:

+const AVATAR_SIZES = {
+  xs: "24px",
+  sm: "32px",
+  md: "40px",
+  lg: "70px",
+  xl: "96px",
+} as const;
+
+const AVATAR_SHAPES = {
+  rounded: "4px",
+  square: "0px",
+  circle: "50%",
+} as const;
+
 function getAvatarSize(size: AvatarSize) {
-  switch (size) {
-    case "xs":
-      return "24px";
-    case "sm":
-      return "32px";
-    case "md":
-      return "40px";
-    case "lg":
-      return "70px";
-    case "xl":
-      return "96px";
-    default:
-      return "40px";
-  }
+  return AVATAR_SIZES[size] ?? AVATAR_SIZES.md;
 }
 
 function getAvatarShape(shape: AvatarShape) {
-  switch (shape) {
-    case "rounded":
-      return "4px";
-    case "square":
-      return "0px";
-    default:
-      return "50%";
-  }
+  return AVATAR_SHAPES[shape] ?? AVATAR_SHAPES.circle;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf0be64 and 08e2972.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/avatar/global.d.ts (1 hunks)
  • packages/avatar/package.json (1 hunks)
  • packages/avatar/src/Avatar.test.tsx (1 hunks)
  • packages/avatar/src/Avatar.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/avatar/global.d.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/avatar/src/Avatar.test.tsx
🔇 Additional comments (4)
packages/avatar/package.json (2)

42-42: 🛠️ Refactor suggestion

@testing-library/react 버전 업데이트가 필요합니다

현재 사용 중인 버전(^16.0.1)이 최신 버전이 아닙니다.

다음과 같이 수정해주세요:

-    "@testing-library/react": "^16.0.1",
+    "@testing-library/react": "^14.1.2",

Likely invalid or redundant comment.


11-11: ⚠️ Potential issue

소스 파일이 아닌 배포된 파일을 내보내도록 수정이 필요합니다

exports 필드가 소스 파일을 직접 가리키고 있습니다. 배포된 패키지는 컴파일된 파일을 참조해야 합니다.

다음과 같이 수정해주세요:

-  "exports": "./src/index.ts",
+  "exports": {
+    ".": {
+      "import": "./dist/index.js",
+      "require": "./dist/index.cjs",
+      "types": "./dist/index.d.ts"
+    }
+  }

Likely invalid or redundant comment.

packages/avatar/src/Avatar.tsx (2)

51-51: 🛠️ Refactor suggestion

ref 타입을 더 구체적으로 지정해주세요

ForwardedRef<any> 대신 더 구체적인 타입을 사용하면 타입 안전성이 향상됩니다.

다음과 같이 수정해주세요:

-  ref: ForwardedRef<any>
+  ref: ForwardedRef<HTMLDivElement>

Likely invalid or redundant comment.


69-80: 🛠️ Refactor suggestion

접근성 개선이 필요합니다

스크린 리더 사용자를 위한 적절한 ARIA 속성이 누락되어 있습니다.

다음과 같이 수정해주세요:

 {src ? (
   <img
     src={src}
     alt={alt}
+    aria-invalid={false}
     onError={(e) => {
-      if (fallback) e.currentTarget.src = fallback;
+      if (fallback) {
+        e.currentTarget.src = fallback;
+        e.currentTarget.setAttribute('aria-invalid', 'true');
+      }
     }}
     className={styles.image}
   />
 ) : (
-  <span className={styles.fallback}>{alt || fallback}</span>
+  <span className={styles.fallback} role="img" aria-label={alt || fallback}>
+    {alt || fallback}
+  </span>
 )}

Likely invalid or redundant comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/avatar/src/Avatar.tsx (1)

85-111: 헬퍼 함수의 성능을 개선할 수 있습니다

switch 문 대신 객체 매핑을 사용하면 더 효율적일 수 있습니다.

-function getAvatarSize(size: AvatarSize) {
-  switch (size) {
-    case "xs":
-      return "24px";
-    case "sm":
-      return "32px";
-    case "md":
-      return "40px";
-    case "lg":
-      return "70px";
-    case "xl":
-      return "96px";
-    default:
-      return "40px";
-  }
-}
+const AVATAR_SIZES: Record<AvatarSize, string> = {
+  xs: "24px",
+  sm: "32px",
+  md: "40px",
+  lg: "70px",
+  xl: "96px",
+};
+
+function getAvatarSize(size: AvatarSize) {
+  return AVATAR_SIZES[size] ?? "40px";
+}

-function getAvatarShape(shape: AvatarShape) {
-  switch (shape) {
-    case "rounded":
-      return "4px";
-    case "square":
-      return "0px";
-    default:
-      return "50%";
-  }
-}
+const AVATAR_SHAPES: Record<AvatarShape, string> = {
+  rounded: "4px",
+  square: "0px",
+  circle: "50%",
+};
+
+function getAvatarShape(shape: AvatarShape) {
+  return AVATAR_SHAPES[shape] ?? "50%";
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d41c9a6 and cce1e51.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • packages/avatar/.storybook/main.ts (1 hunks)
  • packages/avatar/.storybook/preview.ts (1 hunks)
  • packages/avatar/global.d.ts (1 hunks)
  • packages/avatar/package.json (1 hunks)
  • packages/avatar/src/Avatar.module.css (1 hunks)
  • packages/avatar/src/Avatar.stories.tsx (1 hunks)
  • packages/avatar/src/Avatar.test.tsx (1 hunks)
  • packages/avatar/src/Avatar.tsx (1 hunks)
  • packages/avatar/src/index.ts (1 hunks)
  • packages/avatar/tsconfig.json (1 hunks)
  • packages/avatar/tsup.config.ts (1 hunks)
  • packages/avatar/vitest.config.ts (1 hunks)
  • packages/avatar/vitest.setup.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/avatar/global.d.ts
  • packages/avatar/vitest.setup.ts
  • packages/avatar/tsup.config.ts
  • packages/avatar/.storybook/preview.ts
  • packages/avatar/src/index.ts
  • packages/avatar/tsconfig.json
  • packages/avatar/src/Avatar.module.css
  • packages/avatar/.storybook/main.ts
  • packages/avatar/vitest.config.ts
  • packages/avatar/src/Avatar.stories.tsx
  • packages/avatar/src/Avatar.test.tsx
  • packages/avatar/package.json
🔇 Additional comments (3)
packages/avatar/src/Avatar.tsx (3)

11-29: 타입 정의가 명확하고 잘 문서화되어 있습니다!

크기와 모양에 대한 타입 정의가 한글 주석과 함께 잘 문서화되어 있습니다.


51-51: ref 타입을 더 구체적으로 지정해주세요

ForwardedRef<any> 대신 더 구체적인 타입을 사용하는 것이 좋습니다.

-  ref: ForwardedRef<any>
+  ref: ForwardedRef<HTMLDivElement>

69-80: 접근성 개선이 필요합니다

스크린 리더 사용자를 위한 접근성 개선이 필요합니다:

  • 이미지 로딩 실패 시 적절한 피드백
  • 대체 텍스트에 대한 적절한 role 속성
{src ? (
  <img
    src={src}
    alt={alt}
+   aria-invalid={false}
    onError={(e) => {
-     if (fallback) e.currentTarget.src = fallback;
+     if (fallback) {
+       e.currentTarget.src = fallback;
+       e.currentTarget.setAttribute('aria-invalid', 'true');
+     }
    }}
    className={styles.image}
  />
) : (
-  <span className={styles.fallback}>{alt || fallback}</span>
+  <span className={styles.fallback} role="img" aria-label={alt || fallback}>
+    {alt || fallback}
+  </span>
)}

@noahluftyang noahluftyang dismissed heeji289’s stale review January 9, 2025 14:53

Already review completed

@noahluftyang noahluftyang merged commit f527341 into main Jan 9, 2025
5 of 6 checks passed
@noahluftyang noahluftyang deleted the feat/avatar branch January 9, 2025 14:53
Copy link

codecov bot commented Jan 9, 2025

Codecov Report

Attention: Patch coverage is 99.20635% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/avatar/src/Avatar.tsx 98.46% 1 Missing ⚠️
Files with missing lines Coverage Δ
packages/avatar/src/Avatar.test.tsx 100.00% <100.00%> (ø)
packages/avatar/src/Avatar.tsx 98.46% <98.46%> (ø)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Avatar
4 participants