Skip to content

[Step1] hippo: styled-components 적용하기 - #1

Open
meteorqz6 wants to merge 16 commits into
hippo-step5from
hippo-adv-1
Open

[Step1] hippo: styled-components 적용하기#1
meteorqz6 wants to merge 16 commits into
hippo-step5from
hippo-adv-1

Conversation

@meteorqz6

@meteorqz6 meteorqz6 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

개인 목표 달성 여부

  • CSS Modules → styled-components 마이그레이션을 직접 하며 두 방식의 차이를 체감했다.
  • 기본 스타일링, 중첩 선택자, styled(Component) 확장 패턴을 실제 코드에 적용했다.
  • 기능 변경 없이 스타일링 방식만 교체하는 리팩토링을 완료했다.

리뷰어에게

특히 봐줬으면 하는 부분, 확신이 없는 코드, 논의하고 싶은 것

  • 자식 선택자 중첩 — 언제 쓰고 언제 피할까에 대한 리뷰어님의 의견이 궁금합니다!

Summary by CodeRabbit

릴리스 노트

  • Documentation

    • 학습 가이드 문서 업데이트 및 재구성
  • Dependencies

    • styled-components 패키지 추가
  • Refactor

    • 컴포넌트 파일 구조 정리 및 스타일 시스템 개선
    • 색상 토큰 변수 확장

@meteorqz6 meteorqz6 self-assigned this Jun 15, 2026
@meteorqz6
meteorqz6 marked this pull request as draft June 15, 2026 16:11
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

CSS 모듈 기반 서브디렉터리 구조(Header/, CategoryFilter/, Modal/, RestaurantList/, RestaurantDetailModal/, AddRestaurantModal/)를 제거하고, styled-components를 적용한 단일 파일 컴포넌트 5종으로 대체합니다. package.jsonstyled-components 의존성을 추가하고, CSS 변수와 과제 문서도 함께 갱신합니다.

Changes

styled-components 마이그레이션

Layer / File(s) Summary
의존성·CSS 토큰·임포트 경로 업데이트
package.json, src/App.css, src/App.jsx
styled-components ^6.4.2 의존성을 추가하고, :root--grey-50·--grey-150 변수를 확장하며, App.jsx의 컴포넌트 임포트 경로를 평탄한 단일 파일 구조로 변경합니다.
Modal 기반 컴포넌트 재구현
src/components/Modal.jsx, src/components/Modal/Modal.jsx, src/components/Modal/Modal.module.css
Modal을 styled-components 기반 단일 파일로 재구현하고, Escape 키·백드롭 클릭 닫기 동작을 유지하면서 CSS 모듈 구현체와 스타일 파일을 제거합니다.
Header·CategoryFilter·RestaurantList 재구현
src/components/Header.jsx, src/components/CategoryFilter.jsx, src/components/RestaurantList.jsx, src/components/Header/*, src/components/CategoryFilter/*, src/components/RestaurantList/*
세 컴포넌트를 styled-components 기반 단일 파일로 각각 신규 추가하고, 기존 서브디렉터리 내 JSX 구현체와 CSS 모듈 파일을 모두 제거합니다.
RestaurantDetailModal·AddRestaurantModal 재구현
src/components/RestaurantDetailModal.jsx, src/components/AddRestaurantModal.jsx, src/components/RestaurantDetailModal/*, src/components/AddRestaurantModal/*
두 모달 컴포넌트를 styled-components 기반 단일 파일로 재구현하고, 기존 서브디렉터리 JSX·CSS 모듈 파일을 제거합니다.
과제 README 업데이트
README.md, 01-styled-components/README.md, 01-first-component/README.md, 02-rendering-lists/README.md, 03-modal/README.md, 04-form/README.md, 05-effects/README.md
루트 README를 styled-components 리팩토링 학습 내용으로 전면 교체하고, 01-styled-components/README.md에 신규 과제 요구사항을 추가하며, 이전 과제 README들의 내용을 제거합니다.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed styled-components 적용으로 CSS Modules를 리팩터링하는 이번 변경의 핵심을 잘 요약합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hippo-adv-1

Comment @coderabbitai help to get the list of available commands.

@meteorqz6 meteorqz6 changed the title Hippo adv 1 [Step1] hippo - styled-components 적용 Jun 15, 2026
@meteorqz6 meteorqz6 changed the title [Step1] hippo - styled-components 적용 [Step1] hippo: styled-components 적용 Jun 16, 2026
@meteorqz6
meteorqz6 marked this pull request as ready for review June 16, 2026 06:13
@meteorqz6

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/components/AddRestaurantModal.jsx (1)

6-25: ⚡ Quick win

라벨 스타일은 child selector 중첩보다 명시적 컴포넌트 분리가 더 안전합니다.

현재 구조는 FormItem의 하위에 label이 있다는 전제에 의존해서, 마크업이 바뀌면 스타일이 같이 깨지기 쉽습니다. FormLabel/RequiredFormLabel을 별도 styled 컴포넌트로 분리하면 재사용성과 변경 안정성이 좋아집니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/AddRestaurantModal.jsx` around lines 6 - 25, The current
implementation relies on child selector nesting where label styling is defined
inside FormItem and RequiredFormItem, which is fragile if the HTML structure
changes. Extract the label styling into separate styled components: create a
FormLabel styled component containing the current label styles from FormItem,
and a RequiredFormLabel styled component that extends FormLabel with the
asterisk styling currently in RequiredFormItem. This makes the components more
explicit, reusable, and less dependent on specific DOM hierarchy assumptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 142-152: The markdown code blocks in README.md starting at line
142 are missing language specification after the opening triple backticks, which
violates markdown linter rule MD040. Add a language identifier after the opening
triple backticks of the code blocks. Since these blocks show file structure, use
`text` as the language specifier (e.g., change the opening ``` to ```text).
Ensure all code blocks have proper opening and closing triple backticks with the
appropriate language specified.

In `@src/components/Header.jsx`:
- Line 46: The img element at line 46 that displays the addButton icon is
missing an alt attribute, which is required for accessibility. Since this img is
a visual decoration element for the button and the button's accessibility name
is already provided by the aria-label attribute on line 43, add an empty alt
attribute (alt="") to the img element to properly indicate that it is decorative
and should be ignored by screen readers.

In `@src/components/Modal.jsx`:
- Around line 41-43: The ModalContainer element in Modal.jsx (lines 41-43) is
missing critical accessibility attributes required for keyboard navigation and
screen reader support. Add the role="dialog" attribute to the ModalContainer to
identify it as a dialog, add aria-modal="true" to indicate it's a modal overlay,
and connect the ModalTitle to the container using aria-labelledby with matching
IDs so screen readers announce the title. Additionally, implement focus
management by ensuring keyboard focus moves into the modal on opening (typically
to the first focusable element or the title) and returns to the previously
focused element when the modal closes, which prevents focus from escaping to the
background and ensures proper context for keyboard users.

In `@src/components/RestaurantList.jsx`:
- Line 73: The Button component on line 73 is missing the type attribute, which
can cause unintended form submission behavior when the button is rendered inside
a form element. Add type="button" to the Button component to explicitly prevent
the default form submission and ensure only the onRestaurantClick handler is
executed when clicked.

---

Nitpick comments:
In `@src/components/AddRestaurantModal.jsx`:
- Around line 6-25: The current implementation relies on child selector nesting
where label styling is defined inside FormItem and RequiredFormItem, which is
fragile if the HTML structure changes. Extract the label styling into separate
styled components: create a FormLabel styled component containing the current
label styles from FormItem, and a RequiredFormLabel styled component that
extends FormLabel with the asterisk styling currently in RequiredFormItem. This
makes the components more explicit, reusable, and less dependent on specific DOM
hierarchy assumptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: db9743f4-3d8c-4676-b58e-bbc6121dca6c

📥 Commits

Reviewing files that changed from the base of the PR and between 1f0cb94 and 00cd29d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • 01-first-component/README.md
  • 01-styled-components/README.md
  • 02-rendering-lists/README.md
  • 03-modal/README.md
  • 04-form/README.md
  • 05-effects/README.md
  • README.md
  • package.json
  • src/App.css
  • src/App.jsx
  • src/components/AddRestaurantModal.jsx
  • src/components/AddRestaurantModal/AddRestaurantModal.jsx
  • src/components/AddRestaurantModal/AddRestaurantModal.module.css
  • src/components/CategoryFilter.jsx
  • src/components/CategoryFilter/CategoryFilter.jsx
  • src/components/CategoryFilter/CategoryFilter.module.css
  • src/components/Header.jsx
  • src/components/Header/Header.jsx
  • src/components/Header/Header.module.css
  • src/components/Modal.jsx
  • src/components/Modal/Modal.jsx
  • src/components/Modal/Modal.module.css
  • src/components/RestaurantDetailModal.jsx
  • src/components/RestaurantDetailModal/RestaurantDetailModal.jsx
  • src/components/RestaurantDetailModal/RestaurantDetailModal.module.css
  • src/components/RestaurantList.jsx
  • src/components/RestaurantList/RestaurantList.jsx
  • src/components/RestaurantList/RestaurantList.module.css
💤 Files with no reviewable changes (17)
  • 01-first-component/README.md
  • 04-form/README.md
  • src/components/AddRestaurantModal/AddRestaurantModal.jsx
  • src/components/RestaurantList/RestaurantList.module.css
  • 03-modal/README.md
  • src/components/RestaurantDetailModal/RestaurantDetailModal.jsx
  • src/components/Modal/Modal.jsx
  • 05-effects/README.md
  • src/components/Header/Header.module.css
  • src/components/Modal/Modal.module.css
  • src/components/Header/Header.jsx
  • 02-rendering-lists/README.md
  • src/components/CategoryFilter/CategoryFilter.module.css
  • src/components/RestaurantDetailModal/RestaurantDetailModal.module.css
  • src/components/CategoryFilter/CategoryFilter.jsx
  • src/components/AddRestaurantModal/AddRestaurantModal.module.css
  • src/components/RestaurantList/RestaurantList.jsx

Comment thread README.md
Comment thread src/components/Header.jsx
Comment thread src/components/Modal.jsx
Comment thread src/components/RestaurantList.jsx

@ehlung ehlung left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

자식 선택자 중첩 질문 주신 부분에 대해 제 생각도 남겨볼게요!
README에 정리해주신 의미 있는 콘텐츠는 분리하고, 단순 아이콘은 중첩하는 기준에 동의합니다.

여기에 더해서 선택자의 정밀도도 기준이 될 수 있다고 생각합니다. 자식 선택자(img { })는 부모 컴포넌트 안에 있는 모든 img 태그에 무조건 적용됩니다. 예를 들어 나중에 GnbButton 안에 알림 뱃지 같은 다른 이미지가 추가되면, 의도치 않게 그 이미지에도 같은 스타일이 적용될 수 있습니다.

그래서 자식 선택자 중첩을 결정할 때는 '콘텐츠로서 의미가 있는지'와 '구조가 바뀔 때도 스타일이 의도한 요소에만 적용되는지'를 같이 보고 상황에 따라 섞어서 사용하면 될 것 같아요! 스터디 때 좀 더 논의해봅시다!

Comment on lines +19 to +25
const RequiredFormItem = styled(FormItem)`
label::after {
padding-left: 4px;
color: var(--primary-color);
content: "*";
}
`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[논의]
필수 항목 표시(*)를 RequiredFormItem = styled(FormItem)으로 확장해서 처리한 방식 좋네요! 저는 같은 문제를 $required prop으로 분기 처리했는데, 비교해보니 트레이드오프가 있는 것 같아요.

styled(Component) 확장은 variant마다 이름 있는 컴포넌트가 생겨서 의도가 명확하다는 장점이 있는 반면, variant가 늘어나면 컴포넌트 개수도 같이 늘어날 것 같아요. 저처럼 props로 처리하면 컴포넌트 하나로 여러 variant를 다룰 수 있지만, 조건이 많아지면 템플릿 리터럴 안 분기가 복잡해지는 단점이 있더라고요.

지금 규모에서는 두 방식 다 괜찮은 것 같은데, variant가 더 늘어날 걸 가정하면 어느 쪽이 더 나을지 스터디 때 이야기해보면 좋을 것 같습니다!

Comment thread src/components/Header.jsx
Comment on lines +28 to +34
img {
display: block;
width: 40px;
height: 40px;
object-fit: contain;
}
`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[배움]
저는 CSS 모듈에서도 아이콘에 별도 클래스를 지정해놨어서 styled-components로 옮길 때도 별도 컴포넌트로 분리했는데, 팀원 코드 보니 이 부분은 중첩이 더 간결한 선택일 수도 있겠네요.

Comment on lines +4 to +7
const List = styled.ul`
padding: 0 16px;
margin: 16px 0;
`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[질문]
section+ul 이중 구조를 ul 하나로 단일화하신 점이 독특하네요! 저는 기존의 이중 구조를 유지했는데, section이 리스트 영역이라는 의미를 명시적으로 드러내준다고 생각해서였어요.
다만 지금처럼 section 안에 ul 하나만 있는 경우엔 굳이 감쌀 필요가 있나 싶기도 해서, 더 단순한 구조도 충분히 설득력 있어 보입니다! DOM 노드 하나 줄이는 것과 시맨틱 명시 사이에서 어떤 기준으로 선택하셨는지 궁금해요.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

<ul> 자체가 항목들의 목록이라는 의미를 가진 시맨틱 요소라서, 음식점 목록이라는 의도를 <ul>만으로 충분히 전달할 수 있다고 판단했습니다.

Comment thread src/App.css
Comment on lines +22 to +24
--grey-50: #fcfcfd;
--grey-100: #ffffff;
--grey-150: #e9eaed;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[배움]
색상 하드코딩을 :root 변수로 옮기신 부분이 인상적이네요!
저는 미션 요구사항에서 App.css를 고정해놔서 그대로 styled-components 스타일로 변환하는 것에만 신경썼는데, 세심한 접근인 것 같아요.

처음에는 제약 사항을 어기는 것이 아닌가? 하는 생각이 들었는데, 이번 미션 제약의 타겟은 컴포넌트별 스타일 클래스가 App.css에 남아있는 것을 막는 것이지, 색상 변수를 추가하는 것 자체를 막으려는 의도는 아닐 가능성이 크다고 판단했습니다.

색상 변수는 컴포넌트 스타일이 아니라 디자인 토큰이기 때문에 styled-components 안에서도 var()로 그대로 참조되니, 토큰을 추가하는 건 미션 취지에 어긋나지 않는다고 봐서 저도 수정 반영했습니다!

@meteorqz6 meteorqz6 changed the title [Step1] hippo: styled-components 적용 [Step1] hippo: styled-components 적용하기 Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants