Skip to content

Feat/#53 JD 분석 폼 페이지 UI 구현 - #56

Merged
leeleeleeleejun merged 13 commits into
devfrom
feat/#53
Jul 10, 2026
Merged

leeleeleeleejun merged 13 commits into
devfrom
feat/#53

Conversation

@leeleeleeleejun

@leeleeleeleejun leeleeleeleejun commented Jul 10, 2026 •

Copy link
Copy Markdown
Member

#️⃣연관된 이슈

📝작업 내용

홈 진입 화면과 JD(채용 공고) 분석 폼 UI를 구현했습니다. (현재 API 미연동, UI 확인용)

  • JD 분석 폼 (JDAnalysisForm)

    • 공고 링크(URL)/원문 입력 → 직무 선택 단계로 전환되는 흐름
    • INPUT / SELECT_POSITION phase 기반 단계 전환
  • 홈 화면 / 라우팅

    • HomePage를 JD 분석 진입 화면으로 개편
    • (with_sidebar)/page.tsx → /home으로 이동, 루트(/)는 /home으로 리다이렉트 (랜딩 페이지 자리)
  • 공용 컴포넌트

    • RadioGroup, RadioGroupItem 신규 구현
    • SelectedControl 배경/테두리 스타일 수정
    • Button fullWidth prop 추가
  • 기타

    • motion 패키지 추가
    • 사이드바 상태에 따른 토스트 위치 조정 (사이드바 영역 제외하고 center 위치 계산)

스크린샷 (선택)

image image

💬리뷰 요구사항(선택)

  • 단일 직무면 선택 단계를 건너뛰고 다중 직무면 선택 폼으로 전환하는 흐름을 설계 중입니다.
    API가 단일/분리 중 어느 형태로 확정되느냐에 따라 상태 소유 구조가 달라질 예정입니다

Summary by CodeRabbit

Summary by CodeRabbit

  • 새 기능
    • 홈에서 공고 분석 입력 → 포지션 선택 → 생성 흐름의 UI를 추가했습니다.
    • 라디오 그룹/옵션 컴포넌트를 새로 제공했습니다.
    • 버튼에 전체 너비(fullWidth) 옵션을 추가했습니다.
  • UI 개선
    • 토스트가 사이드바 확장/축소 상태에 맞춰 가로 위치를 조정합니다.
    • 사이드바 레이아웃의 높이/너비 전환 동작을 개선했습니다.
  • 문서
    • 라디오 그룹 Storybook 스토리를 추가했습니다.

@leeleeleeleejun leeleeleeleejun self-assigned this Jul 10, 2026
@leeleeleeleejun leeleeleeleejun added 🎨 Style 스타일 관련 🙋‍♂️ Question Further information is requested labels Jul 10, 2026
@leeleeleeleejun leeleeleeleejun linked an issue Jul 10, 2026 that may be closed by this pull request
1 task
@vercel

vercel Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
28th-web-team-1-fe Ready Ready Preview, Comment Jul 10, 2026 10:45am

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b4ba1bc5-4f42-434f-9b4e-ee50bd010e3d

📥 Commits

Reviewing files that changed from the base of the PR and between c38c89b and 5fed40f.

📒 Files selected for processing (3)
  • lefthook.yml
  • src/shared/ui/button/Button.stories.tsx
  • src/shared/ui/button/Button.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/shared/ui/button/Button.tsx

Walkthrough

루트 경로가 /home으로 리다이렉트되고, 홈 화면이 공고 입력·직무 선택 단계형 UI로 변경되었습니다. RadioGroup과 Button 기능이 확장되었으며, 사이드바·토스트·레이아웃 스타일과 lint 설정 및 의존성이 조정되었습니다.

Changes

홈 공고 분석 기능

Layer / File(s) Summary
분석 UI 컴포넌트 계약
src/shared/ui/radio_group/*, src/shared/ui/button/*
Radix 기반 RadioGroup과 RadioGroupItem이 추가되고, Button에 fullWidth 옵션과 Storybook 예시가 추가되었습니다.
공고 분석 단계 흐름
src/views/home/ui/*, package.json, eslint.config.mjs, lefthook.yml
홈 화면이 JDAnalysisForm을 렌더링하고, 입력·직무 선택 단계 전환과 motion 애니메이션, toast 기반 확인 메시지를 제공합니다. lint 및 typecheck 설정도 변경되었습니다.
라우팅 및 앱 셸 조정
app/page.tsx, src/widgets/sidebar/ui/sidebar.tsx, src/app/layouts/*, src/app/style/globals.css, src/shared/ui/toast/Toast.tsx, src/shared/ui/selected_control/SelectedControl.tsx
루트 페이지가 /home으로 이동하고, 사이드바 상태·링크·너비 변수, 토스트 위치, 레이아웃 높이 및 선택 컨트롤 스타일이 변경되었습니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant RootPage
  participant HomePage
  participant JDAnalysisForm
  participant Toast
  Browser->>RootPage: 루트 페이지 로드
  RootPage->>Browser: /home으로 push
  Browser->>HomePage: 홈 화면 렌더링
  HomePage->>JDAnalysisForm: 공고 분석 폼 표시
  JDAnalysisForm->>Toast: 단계 제출 시 확인 메시지 표시
  JDAnalysisForm->>JDAnalysisForm: 입력 단계와 직무 선택 단계 전환
Loading

Suggested labels: ✨ Feature

Poem

당근 문 토끼가 폼을 열고
공고를 살포시 담았네.
라디오 톡, 버튼은 쭉—
홈으로 깡충, 토스트는 반짝.
새 화면이 꽃처럼 피었네!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR의 핵심인 JD 분석 폼과 홈 화면 UI 구현을 간결하게 잘 요약한 제목입니다.
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.
✨ 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 feat/#53

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 2

🧹 Nitpick comments (7)
src/shared/ui/toast/Toast.tsx (1)

54-61: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

사이드바 너비 매직 넘버를 상수로 추출하는 것을 권장합니다.

110px와 38px가 사이드바 확장/축소 너비와 직접 연결되어 있으나, 하드코딩되어 있어 사이드바 너비 변경 시 수동 업데이트가 필요합니다. 사이드바 너비 상수를 공유하거나 CSS 변수로 관리하는 것을 고려해보세요.

🤖 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/shared/ui/toast/Toast.tsx` around lines 54 - 61, Extract the sidebar
offset values used in the styled block of Toast into shared sidebar width
constants or CSS variables, replacing the hardcoded 110px and 38px values while
preserving the expanded and collapsed positioning behavior.
src/views/home/ui/JDAnalysisForm.tsx (3)

128-130: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

fullWidth prop 대신 className='w-full' 사용 중.

PR에서 Button에 fullWidth prop이 추가되었으나, JDSelectStep의 제출 버튼에서는 className={'w-full'}로 너비를 지정하고 있습니다. fullWidth prop 사용으로 일관성을 유지하는 것을 권장합니다.

♻️ fullWidth prop 사용 제안
-        <Button type={'submit'} size={'xl'} className={'w-full'}>
+        <Button type={'submit'} size={'xl'} fullWidth>
          이력서 생성하러 가기
        </Button>
🤖 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/views/home/ui/JDAnalysisForm.tsx` around lines 128 - 130, JDAnalysisForm의
제출 Button에서 className={'w-full'} 대신 새로 추가된 fullWidth prop을 사용하도록 변경해 너비 지정 방식을
일관되게 맞추세요.

86-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

공용 Button 컴포넌트 대신 raw <button> 사용 중.

PR 목표에 따라 Button 컴포넌트에 fullWidth prop이 추가되었으나, JDInputStep의 제출 버튼은 raw <button>으로 구현되어 있습니다. 디자인 시스템 일관성을 위해 공용 Button 컴포넌트 사용을 권장합니다.

♻️ Button 컴포넌트 사용 제안
-        <button type={'submit'} aria-label="JD 분석" className="bg-btn-primary-fill ml-auto w-fit rounded-lg p-3.5 text-white">
-          <ArrowRightIcon size={20} />
-        </button>
+        <Button type={'submit'} aria-label="JD 분석" size={'lg'} className="ml-auto w-fit">
+          <ArrowRightIcon size={20} />
+        </Button>
🤖 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/views/home/ui/JDAnalysisForm.tsx` around lines 86 - 88, JDAnalysisForm의
JDInputStep 제출 버튼이 공용 Button 컴포넌트 대신 raw button을 사용하고 있습니다. 해당 버튼을 Button으로
교체하고, 기존 submit 동작·aria-label·아이콘·스타일을 유지하며 필요한 경우 추가된 fullWidth prop을 적용하세요.

73-84: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

textarea에 focus 및 border 스타일 부재.

textarea에 outline-none이 적용되어 있으나 포커스 시 시각적 피드백(border, ring 등)이 없습니다. 접근성 및 UX 관점에서 포커스 상태 스타일 추가를 권장합니다.

♻️ 포커스 스타일 추가 제안
           className={cn(
             'field-sizing-content',
             'max-h-24 min-h-0 w-full',
             'text-body1 text-text-basic',
-            'resize-none overflow-y-auto outline-none',
+            'resize-none overflow-y-auto outline-none',
+            'border-border-subtler rounded-lg border',
+            'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3',
             'placeholder:text-body1 placeholder:text-text-subtler'
           )}
🤖 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/views/home/ui/JDAnalysisForm.tsx` around lines 73 - 84, The textarea in
JDAnalysisForm lacks visible focus feedback because its outline is removed.
Update the textarea class list to add accessible focus-state styling, such as a
focus-visible border or ring, while preserving the existing layout and
typography classes.
eslint.config.mjs (1)

118-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

비활성화된 규칙과 주석 간 모순 정리 필요.

react/jsx-handler-names 규칙이 주석 처리되었지만, 상단 설명 주석(118-122)은 여전히 "이벤트 핸들러 handle prefix 강제"라고 작성되어 있어 실제 동작과 모순됩니다. 주석을 규칙 비활성션 사유와 함께 업데이트하거나, 규칙을 재활성화해 주세요.

♻️ 주석 업데이트 제안
       // ────────────────────────────────────────────────
-      // 이벤트 핸들러 handle prefix 강제
-      // - JSX prop에 전달되는 함수: handle prefix 강제
-      // - 로컬 변수로 선언된 핸들러도 함께 체크
+      // 이벤트 핸들러 handle prefix 규칙 (현재 비활성화)
+      // - react/jsx-handler-names 규칙은 프로젝트 요구사항에 따라 비활성화됨
       // ────────────────────────────────────────────────
-      // 'react/jsx-handler-names': [
-      //   'error',
-      //   {
-      //     eventHandlerPrefix: 'handle', // 함수 이름은 handle로 시작
-      //     eventHandlerPropPrefix: 'on', // prop 이름은 on으로 시작
-      //     checkLocalVariables: true, // 로컬 변수에 할당된 핸들러도 체크
-      //     checkInlineFunction: false // 인라인 함수 (() => {}) 는 허용
-      //   }
-      // ],
+      // 'react/jsx-handler-names': [
+      //   'error',
+      //   {
+      //     eventHandlerPrefix: 'handle',
+      //     eventHandlerPropPrefix: 'on',
+      //     checkLocalVariables: true,
+      //     checkInlineFunction: false
+      //   }
+      // ],
🤖 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 `@eslint.config.mjs` around lines 118 - 131, Resolve the contradiction around
the disabled react/jsx-handler-names rule: either uncomment and configure the
rule as described by the Korean comments, or update the surrounding comments to
state that the rule is disabled and document the reason. Keep the comments and
actual ESLint behavior consistent in the configuration section.
src/widgets/sidebar/ui/sidebar.tsx (1)

18-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

data-sidebar 속성값과 isCollapsed 변수명 간 의미 모순.

isCollapsed가 true일 때 data-sidebar="expanded"가 설정됩니다. 변수명 isCollapsed는 "접힘"을 의미하지만, 실제로는 true일 때 사이드바가 펼쳐진 상태(w-55, Heading 표시, 라벨 표시)로 동작합니다. data-sidebar 속성값은 실제 동작 기준으로는 맞지만, 변수명과 모순되어 향후 유지보수에 혼란을 줄 수 있습니다.

♻️ 변수명 수정 제안
-  const [isCollapsed, setIsCollapsed] = useState<boolean>(true)
+  const [isExpanded, setIsExpanded] = useState<boolean>(true)

그리고 관련 참조 일괄 수정:

-      data-sidebar={isCollapsed ? 'expanded' : 'collapsed'}
+      data-sidebar={isExpanded ? 'expanded' : 'collapsed'}
-      className={cn('bg-bg-gray-subtler flex h-full flex-col px-4 py-5', 'transition-all duration-300 ease-in-out', isCollapsed ? 'w-55' : 'w-19')}
+      className={cn('bg-bg-gray-subtler flex h-full flex-col px-4 py-5', 'transition-all duration-300 ease-in-out', isExpanded ? 'w-55' : 'w-19')}
-      <header className={cn('flex h-10', isCollapsed ? 'justify-between' : 'justify-center')}>
+      <header className={cn('flex h-10', isExpanded ? 'justify-between' : 'justify-center')}>
-        {isCollapsed && (
+        {isExpanded && (
-          onClick={() => setIsCollapsed((prev) => !prev)}
+          onClick={() => setIsExpanded((prev) => !prev)}
-          aria-label={isCollapsed ? '사이드바 접기' : '사이드바 펼치기'}
+          aria-label={isExpanded ? '사이드바 접기' : '사이드바 펼치기'}
-        <LinkButton icon={Home} href={'/home'} label={'홈'} isCollapsed={!isCollapsed} />
+        <LinkButton icon={Home} href={'/home'} label={'홈'} isCollapsed={!isExpanded} />
🤖 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/widgets/sidebar/ui/sidebar.tsx` around lines 18 - 20, Rename isCollapsed
to a state name that reflects its actual behavior, such as isExpanded, and
update every related reference in the sidebar component, including the
data-sidebar value and width, heading, and label rendering conditions. Preserve
the existing expanded/collapsed UI behavior while eliminating the naming
contradiction.
app/page.tsx (1)

6-15: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

클라이언트 사이드 리다이렉트보다 서버 사이드 리다이렉트 권장.

useEffect 기반 클라이언트 리다이렉트는 페이지 로드 후 JS 실행 시점에 이동하므로 깜빡임이 발생합니다. TODO 주석에서 임시임을 명시했으므로 긴급하지는 않지만, next.config의 redirects() 또는 Server Component에서 redirect()를 사용하면 더 깔끔한 UX를 제공합니다.

♻️ 서버 사이드 리다이렉트 제안 (next.config.ts)
// next.config.ts
async redirects() {
  return [
    {
      source: '/',
      destination: '/home',
      permanent: false,
    },
  ]
}
🤖 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 `@app/page.tsx` around lines 6 - 15, Replace the client-side
useRouter/useEffect redirect in Page with a server-side redirect: either add a
root-path rule in next.config.ts redirects() targeting /home, or use
redirect('/home') directly in the Page Server Component, and remove the
temporary client-only logic and placeholder markup.
🤖 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 `@src/shared/ui/radio_group/RadioGroup.tsx`:
- Line 21: Update the RadioGroupPrimitive.Item checked-state styling by
replacing the invalid data-checked: Tailwind variant with a selector targeting
Radix’s data-state="checked" attribute, consistent with the existing
group-data-[state=checked] usage in RadioGroup.tsx.

In `@src/views/home/ui/JDAnalysisForm.tsx`:
- Line 110: RadioGroup의 value에 null이 전달되지 않도록 수정하세요. JDAnalysisForm의
RadioGroup에서 value={position}을 value={position ?? undefined}로 변경하거나, position 상태
타입을 string | undefined로 일관되게 변경하세요.

---

Nitpick comments:
In `@app/page.tsx`:
- Around line 6-15: Replace the client-side useRouter/useEffect redirect in Page
with a server-side redirect: either add a root-path rule in next.config.ts
redirects() targeting /home, or use redirect('/home') directly in the Page
Server Component, and remove the temporary client-only logic and placeholder
markup.

In `@eslint.config.mjs`:
- Around line 118-131: Resolve the contradiction around the disabled
react/jsx-handler-names rule: either uncomment and configure the rule as
described by the Korean comments, or update the surrounding comments to state
that the rule is disabled and document the reason. Keep the comments and actual
ESLint behavior consistent in the configuration section.

In `@src/shared/ui/toast/Toast.tsx`:
- Around line 54-61: Extract the sidebar offset values used in the styled block
of Toast into shared sidebar width constants or CSS variables, replacing the
hardcoded 110px and 38px values while preserving the expanded and collapsed
positioning behavior.

In `@src/views/home/ui/JDAnalysisForm.tsx`:
- Around line 128-130: JDAnalysisForm의 제출 Button에서 className={'w-full'} 대신 새로
추가된 fullWidth prop을 사용하도록 변경해 너비 지정 방식을 일관되게 맞추세요.
- Around line 86-88: JDAnalysisForm의 JDInputStep 제출 버튼이 공용 Button 컴포넌트 대신 raw
button을 사용하고 있습니다. 해당 버튼을 Button으로 교체하고, 기존 submit 동작·aria-label·아이콘·스타일을 유지하며
필요한 경우 추가된 fullWidth prop을 적용하세요.
- Around line 73-84: The textarea in JDAnalysisForm lacks visible focus feedback
because its outline is removed. Update the textarea class list to add accessible
focus-state styling, such as a focus-visible border or ring, while preserving
the existing layout and typography classes.

In `@src/widgets/sidebar/ui/sidebar.tsx`:
- Around line 18-20: Rename isCollapsed to a state name that reflects its actual
behavior, such as isExpanded, and update every related reference in the sidebar
component, including the data-sidebar value and width, heading, and label
rendering conditions. Preserve the existing expanded/collapsed UI behavior while
eliminating the naming contradiction.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c00eb40-dec8-48b9-b588-d106260d088d

📥 Commits

Reviewing files that changed from the base of the PR and between 7e6035f and 162cf59.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • app/(with_sidebar)/home/page.tsx
  • app/page.tsx
  • eslint.config.mjs
  • package.json
  • src/app/layouts/RootLayout.tsx
  • src/app/layouts/WithSidebarLayout.tsx
  • src/shared/ui/button/Button.tsx
  • src/shared/ui/radio_group/RadioGroup.stories.tsx
  • src/shared/ui/radio_group/RadioGroup.tsx
  • src/shared/ui/radio_group/index.ts
  • src/shared/ui/selected_control/SelectedControl.tsx
  • src/shared/ui/toast/Toast.tsx
  • src/views/home/ui/HomePage.tsx
  • src/views/home/ui/JDAnalysisForm.tsx
  • src/widgets/sidebar/ui/sidebar.tsx

// Focus
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3',
// Checked
'data-checked:border-border-primary data-checked:bg-element-brand-subtle',

@coderabbitai coderabbitai Bot Jul 10, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

data-checked: Tailwind variant가 Radix UI에서 동작하지 않습니다.

Radix UI RadioGroupPrimitive.Item은 체크 상태를 data-state="checked"로 설정합니다. Tailwind의 data-checked: shorthand는 [data-checked] 속성을 타겟하므로, 이 속성은 Radix가 설정하지 않아 스타일이 적용되지 않습니다. 같은 파일 31행에서 group-data-[state=checked]를 올바르게 사용하고 있는 점과 대조됩니다.

🐛 Proposed fix
         // Checked
-        'data-checked:border-border-primary data-checked:bg-element-brand-subtle',
+        'data-[state=checked]:border-border-primary data-[state=checked]:bg-element-brand-subtle',
📝 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
'data-checked:border-border-primary data-checked:bg-element-brand-subtle',
'data-[state=checked]:border-border-primary data-[state=checked]:bg-element-brand-subtle',
🤖 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/shared/ui/radio_group/RadioGroup.tsx` at line 21, Update the
RadioGroupPrimitive.Item checked-state styling by replacing the invalid
data-checked: Tailwind variant with a selector targeting Radix’s
data-state="checked" attribute, consistent with the existing
group-data-[state=checked] usage in RadioGroup.tsx.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

shadcn/tailwind.css의 @custom-variant data-checked가
[data-state="checked"]를 함께 매칭하도록 정의돼 있어, radix의 data-state="checked"에
data-checked: 스타일이 정상 적용됩니다.

@custom-variant data-checked {
  &:where([data-state="checked"]),   /* radix가 내보내는 속성 */
  &:where([data-checked]:not([data-checked="false"])) { @slot; }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n "custom-variant data-checked" -A5 --type=css . 2>/dev/null
fd -i "tailwind.css" | xargs -I{} sh -c 'echo "== {} =="; cat -n "{}"' 2>/dev/null | head -200
rg -n "custom-variant" -A5 .

Length of output: 717


🏁 Script executed:

#!/bin/bash
rg -n "data-checked" -C3 .

Length of output: 3455


🏁 Script executed:

#!/bin/bash
fd -i "tailwind.config" 
rg -n "data-checked|addVariant|matchVariant" -C3 --type=js --type=ts .
cat package.json | grep -i tailwind
rg -n "custom-variant" -C5 src/app/style/globals.css

Length of output: 4107


🤖 web_search executed:

shadcn tailwind.css @custom-variant data-checked data-state checked

Length of output: 11159


@leeleeleeleejun 확인해봤습니다. src/app/style/globals.css에서 @import 'shadcn/tailwind.css';를 통해 해당 커스텀 배리언트가 프로젝트에 포함되어 있고, shadcn의 tailwind.css에는 실제로 아래와 같은 정의가 있습니다.

`@custom-variant` data-checked {
  &:where([data-state="checked"]),
  &:where([data-checked]:not([data-checked="false"])) { `@slot`; }
}

이 배리언트가 Radix의 data-state="checked"도 함께 매칭하므로, 말씀하신 대로 data-checked: 스타일이 정상적으로 적용됩니다. 제가 놓친 부분이었습니다. 지적 감사합니다 — 이전 코멘트는 철회하겠습니다.

(╹◡╹) 도움이 됐네요!

어떤 직무에 맞는 이력서를 작성해볼까요?
</Text>

<RadioGroup className={'max-h-51.5 overflow-y-auto'} value={position} onValueChange={setPosition}>

@coderabbitai coderabbitai Bot Jul 10, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- JDAnalysisForm.tsx (relevant section) ---'
cat -n src/views/home/ui/JDAnalysisForm.tsx | sed -n '1,220p'

echo
echo '--- locate RadioGroup wrapper/component ---'
rg -n "RadioGroup" src -g '!**/node_modules/**'

echo
echo '--- locate position state declaration/usages ---'
rg -n "position|setPosition" src/views/home/ui/JDAnalysisForm.tsx src -g '!**/node_modules/**'

Repository: YAPP-Github/28th-Web-Team-1-FE

Length of output: 12833


RadioGroup의 value에 null이 들어가지 않도록 수정 필요

src/views/home/ui/JDAnalysisForm.tsx의 position은 string | null인데, RadioGroup의 value는 string | undefined 계열이라 null을 그대로 넘기면 타입 오류가 납니다. position ?? undefined로 넘기거나 상태 타입을 string | undefined로 바꾸세요.

🤖 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/views/home/ui/JDAnalysisForm.tsx` at line 110, RadioGroup의 value에 null이
전달되지 않도록 수정하세요. JDAnalysisForm의 RadioGroup에서 value={position}을 value={position
?? undefined}로 변경하거나, position 상태 타입을 string | undefined로 일관되게 변경하세요.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

radix RadioGroup.Root의 value 타입이 string | null | undefined라 null 허용됩니다
(@radix-ui/react-radio-group 1.4.1). controlled로 쓰고 있어 초기값 null("선택 없음")이
의도된 동작이라 변경하지 않습니다.
image

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The Comment image shows a TypeScript tooltip for RadioGroupProps from @radix-ui/react-radio-group, displaying value?: string | null | undefined, confirming that null is an accepted type for the value prop.

@leeleeleeleejun 확인 감사합니다. 스크린샷대로 @radix-ui/react-radio-group의 RadioGroupProps.value는 string | null | undefined로 정의되어 있어 null이 정상적으로 허용되는 타입이 맞습니다. null을 "선택 없음"의 초기 상태로 사용하는 것이 의도된 설계라면 별도 수정이 필요 없습니다. 제가 잘못 판단했습니다, 코멘트를 철회합니다.

(´• ω •`) ノ

@github-actions

github-actions Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Comment on lines +121 to +124
export const Button = ({ className, variant = 'primary', size = 'lg', asChild = false, fullWidth = false, ...props }: ButtonProps) => {
const COMP = asChild ? Slot.Root : 'button'

return <COMP data-slot="button" data-variant={variant} data-size={size} className={cn(buttonVariants({ variant, size, className }))} {...props} />
return <COMP data-slot="button" data-variant={variant} data-size={size} className={cn(buttonVariants({ variant, size, className }), fullWidth && 'w-full')} {...props} />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

fullWidth를 props로 넘기는것도 좋아보이는데 차라리 className으로 넣는게 어떨까요??

스타일 관련된건 props보다는 className으로 넘기는게 좋아보입니다!

@leeleeleeleejun leeleeleeleejun Jul 10, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

https://heroui.com/en/docs/react/components/button#button-props
https://mui.com/material-ui/api/button/#props

디자인 시스템 라이브러리(버튼)에서 많이 지원하는 패턴이고,
디자인에서 다른 스타일을 함께 커스텀하기보단 w-full 만 사용하는 경우가 많아, 명시적으로 사용할 수 있도록 fullWidth를 따로 생성했습니다!

큰 건 아니라서 컨벤션에 맞게 사용하면 될 듯 합니당
그럼 나중에 w-full 만 사용하는 경우가 많아지면 도입하는 방향으로 고려할까요?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

fullWidth를 props로 해서 관리하는 방향으로 해도 좋을 것 같습니다.
선언적이여서 가독성 측면에서도 괜찮을것 같습니다.

스토리에는 아직 추가가 안된것 같은데 추가해주실 수 있을까요?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

넵 추가해서 merge 하겠습니다~

Comment thread src/shared/ui/toast/Toast.tsx Outdated
Comment on lines +54 to +59
<style>{`
body:has([data-sidebar='expanded']) [data-sonner-toaster][data-x-position='center'] {
transform: translateX(calc(-50% + 110px));
}
}}
{...props}
/>
body:has([data-sidebar='collapsed']) [data-sonner-toaster][data-x-position='center'] {
transform: translateX(calc(-50% + 38px));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

지금은 트랜지션이 없어서 사이드바 여닫는 상태에 따라 토스트 위치가 순간이동할 것 같은데

추후 디자이너분들에게 트랜지션 값에 대해서 받거나 해야될 것 같습니다!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sonner가 toaster에 기본 transition을 적용해 토스트도 같이 따라 동작하고 있습니당
node_modules/sonner/dist/styles.css:51에서 확인할 수 있습니다!

[data-sonner-toaster] {
  ...
  transition: transform 400ms ease;
}

Comment thread eslint.config.mjs
Comment on lines +123 to +131
// 'react/jsx-handler-names': [
// 'error',
// {
// eventHandlerPrefix: 'handle', // 함수 이름은 handle로 시작
// eventHandlerPropPrefix: 'on', // prop 이름은 on으로 시작
// checkLocalVariables: true, // 로컬 변수에 할당된 핸들러도 체크
// checkInlineFunction: false // 인라인 함수 (() => {}) 는 허용
// }
// ],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍👍

Comment thread src/widgets/sidebar/ui/sidebar.tsx Outdated

<nav className={'flex flex-1 flex-col gap-1'}>
<LinkButton icon={Home} href={'/'} label={'홈'} isCollapsed={!isCollapsed} />
<LinkButton icon={Home} href={'/home'} label={'홈'} isCollapsed={!isCollapsed} />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍

Comment thread src/widgets/sidebar/ui/sidebar.tsx Outdated
<aside className={cn('vh-100 bg-bg-gray-subtler flex flex-col px-4 py-5', 'transition-all duration-300 ease-in-out', isCollapsed ? 'w-55' : 'w-19')}>
<aside
data-sidebar={isCollapsed ? 'expanded' : 'collapsed'}
className={cn('bg-bg-gray-subtler flex h-full flex-col px-4 py-5', 'transition-all duration-300 ease-in-out', isCollapsed ? 'w-55' : 'w-19')}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

토스트에서 사이드바 너비를 사용하니까 css 변수로 사이드바 너비를 관리하는건 어떨까요??
자주 바뀔거 같진 않지만 추후 사이드바 너비가 변경될 때 토스트 부분은 누락할 수 있어보입니다.

Comment thread src/widgets/sidebar/ui/sidebar.tsx Outdated
return (
<aside className={cn('vh-100 bg-bg-gray-subtler flex flex-col px-4 py-5', 'transition-all duration-300 ease-in-out', isCollapsed ? 'w-55' : 'w-19')}>
<aside
data-sidebar={isCollapsed ? 'expanded' : 'collapsed'}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

data-sidebar={isCollapsed ? 'expanded' : 'collapsed'}
거꾸로 뒤집혀져 있습니다.
isCollapsed가 true일때 expanded가 되고 false일때 collapsed가 되어있습니다.

@leeleeleeleejun
leeleeleeleejun merged commit 2b71a1e into dev Jul 10, 2026
6 checks passed

This branch was successfully deployed

1 active deployment
Preview — 5fed40f7 Deployed Jul 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🙋‍♂️ Question Further information is requested 🎨 Style 스타일 관련

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] JD 분석 페이지 구현

2 participants