Skip to content

Feature/#64 component feat#65

Merged
yiyoonseo merged 9 commits into
developfrom
feature/#64-compnent-feat
May 22, 2026
Merged

Feature/#64 component feat#65
yiyoonseo merged 9 commits into
developfrom
feature/#64-compnent-feat

Conversation

@yiyoonseo
Copy link
Copy Markdown
Contributor

@yiyoonseo yiyoonseo commented May 22, 2026

🔗 관련 이슈

#64

📋 작업 개요

공통 컴포넌트 UI 개선 작업입니다.

✨ 주요 변경사항

결과 페이지 신규 구현

  • ApplyResult — Trybar + Sidebar + 콘텐츠 영역 전체 레이아웃
  • Trybar — 시도 회차 표시 (sequence API 연동)
  • Sidebar / SidebarItem — 개요 / 개선안 상세 아코디언, 문항별 sub 아이템
  • OverviewSection — 총점 원형 그래프 + 피드백 + 3개 요약 카드
  • ScoreCircle — SVG stroke-dashoffset 기반 원형 점수 그래프
  • Alret — 60점 기준 경고/완료 메시지 분기
  • SummaryCard — 직무적합도 / 성과구체성 / 완성도 카드 (60점 이하 빨간색)

개선안 상세 뷰 (DetailSection)

  • 왼쪽: 질문 + 답변 텍스트, 분석 구간 status별 하이라이트
  • 오른쪽: DetailAnnotationPanel — ChipTag + reason + sentence + 개선 예시
  • 하이라이트 클릭 시 해당 분석만 필터링, 재클릭 시 전체 복원
  • highlightStyles.tsproven / mentioned / fabricated default · selected 스타일 분리

색상 토큰 추가 (color.css)

토큰 용도
green-150 #F3F9E5 proven 하이라이트 배경
green-700 #50B100 proven 텍스트
pink-100 #FFEFFB mentioned 하이라이트 배경
pink-200 #FFE1F8 mentioned 하이라이트 hover
pink-400 #FF29D1 mentioned 텍스트

ChipTag 상태 추가

  • proven (적절함) / mentioned (신뢰성 부족) / fabricated (구체성 부족)

LNB 개선

  • 접기/펼치기 width 트랜지션 (transition-[width] duration-300)
  • 텍스트 레이블 w-0 opacity-0 처리로 자연스러운 페이드
  • 크레딧 클릭 시 /credit 라우팅 연결

기타 공통 컴포넌트

  • Header 좌측 버튼 라벨 "돌아가기" → "메인으로"
  • InputMain iconMap 키 오류 수정 ("PROFILE""ID") 및 점 표기법 오류 수정

API 연동 수정

  • saveApply 요청 바디 오류 수정
  • fetchSelectedQuestions index 기반 ID → analysis.questions 인덱스 조회 통일
  • 결과 페이지 레이아웃 높이 h-screenh-full (헤더 영역 제외)

💡 코드 설명 및 참고사항

📸 스크린샷 (UI 변경 시)

🔍 리뷰 요구사항 (Reviewers)

  • [ ]

⚠️ 로컬 실행 시 유의사항

Summary by CodeRabbit

Release Notes

  • New Features

    • Icon buttons now support small and default size variants
    • Email input field type now supported
    • Navigation sidebar features collapsible folding mode with smooth transitions
    • New icon types added
  • Bug Fixes

    • Updated header navigation label
    • Fixed email field type in login form
    • Enhanced visual feedback for delete actions
  • Style

    • Updated footer branding and layout
    • Updated toast styling

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

This PR extends the icon and button component system with sizing variants, adds EMAIL input type support, refactors the navigation sidebar with smooth fold/unfold transitions, updates footer and header styling, and consolidates auth header logic into a shared utility.

Changes

Component UI System and Navigation Updates

Layer / File(s) Summary
Icon system expansion and asset registry
jobdri/src/components/common/icons/Icon.tsx
Icon.tsx gains CLOSE_S and EMAIL icon imports and registry entries, extending IconType to support size variants and new input icon types.
Button size support
jobdri/src/components/common/buttons/IconButton.tsx, jobdri/src/components/common/buttons/IconOnlyButton.tsx, jobdri/src/app/page.tsx
IconButton and IconOnlyButton now accept optional size prop controlling dimensions and icon selection; demo page shows small variant.
Input component EMAIL type and login flow
jobdri/src/components/common/input/InputMain.tsx, jobdri/src/components/login/EmailLoginScreen.tsx
InputMain supports "EMAIL" type with icon mapping; signup form updated to use EMAIL type; form code reformatted for readability.
Navigation sidebar folded mode with transitions
jobdri/src/components/common/lnb/Lnb.tsx
Lnb refactored to use Logo asset and smooth width/opacity/height transitions for fold/unfold: nav labels collapse, credit/email sections condense vertically, sidebar width animates.
Layout and styling updates
jobdri/src/components/common/header/Header.tsx, jobdri/src/components/common/footer/Footer.tsx, jobdri/src/components/common/footer/BusinessFooter.tsx, jobdri/src/components/common/icons/IconBox.tsx, jobdri/src/components/common/toast/Toast.tsx
Header left action label and click handler refined; Footer background color and BusinessFooter layout spacing updated; IconBox TRASH selected state styled with red background; Toast border-radius adjusted.
Shared auth header extraction
jobdri/src/lib/api/questions.ts
Removes local getAuthHeaders and imports from shared auth module.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • JobDri-Developer/FrontEnd#59: Both PRs refactor the navigation sidebar layout and styling in Lnb.tsx, with #59 focusing on user email source and this PR adding folded mode transitions.
  • JobDri-Developer/FrontEnd#60: Both PRs consolidate auth header logic in the questions API module, incorporating getAuthHeaders for secured requests.
  • JobDri-Developer/FrontEnd#58: Both PRs update the Header component's left action click handler and default navigation behavior in Header.tsx.

Suggested reviewers

  • minnngo

Poem

🐰 With icons now in sizes small and neat,
Buttons shrink and grow to complete the fleet,
Email fields find their home, the sidebar folds with grace,
Transitions smooth and shared auth in its place!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The PR title "Feature/#64 component feat" is vague and uses generic phrasing that doesn't clearly convey the specific changes made in the changeset. Use a more descriptive title that highlights the primary change, such as 'Add size prop to icon buttons and update component styling' or 'Implement UI improvements for result page components'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR addresses issue #64 requirements to modify existing components and implement new components, with changes spanning button sizing, icon updates, footer/header adjustments, input field enhancements, and navigation improvements.
Out of Scope Changes check ✅ Passed All changes appear aligned with issue #64 objectives: button/icon updates, component styling improvements, header/footer adjustments, input enhancements, and LNB modifications are within scope of component development and UI improvements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feature/#64-compnent-feat

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

@yiyoonseo yiyoonseo changed the title Feature/#64 compnent feat Feature/#64 component feat May 22, 2026
Copy link
Copy Markdown

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

🤖 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 `@jobdri/src/components/common/buttons/IconButton.tsx`:
- Around line 31-35: The small variant of IconButton produces
inconsistent/insufficient interior space because padding remains fixed (p-2.5)
while the container and icon classes shrink to h-6 w-6; update IconButton to
compute size-aware spacing: when props.size === "small" set a smaller padding
(e.g., p-1 or p-1.5) or alternatively enforce a minimum container dimension that
accommodates the small icon (adjust the size branch that currently outputs "h-6
w-6"), and ensure the icon element(s) use a matching small icon class rather
than a fixed large icon size; modify the conditional class list in the
IconButton component (the expression that uses size, className, active, and
buttonProps.disabled) so small uses consistent paired container (height/width)
and padding values to prevent layout collapse.

In `@jobdri/src/components/common/buttons/IconOnlyButton.tsx`:
- Line 27: The component IconOnlyButton currently computes closeIconType but
always passes closeIconType to the rendered icon (overriding the public prop
iconType); update the render to prefer the prop iconType when provided and fall
back to closeIconType otherwise (e.g., use iconType if truthy, else
closeIconType) so callers' iconType values are respected; look for the computed
constant closeIconType and the prop iconType in the IconOnlyButton component and
change the value used in the JSX where the icon is rendered.

In `@jobdri/src/components/common/lnb/Lnb.tsx`:
- Around line 158-174: The credit button remains focusable when the LNB is
folded; update the folded branch to make hidden controls non-interactive by
adding aria-hidden={isFold} to the toggle container and make the button
unfocusable when folded (e.g., set tabIndex={isFold ? -1 : 0} and
aria-hidden={isFold} on the <button> in the block that contains isFold), or
alternatively render null when folded; target the JSX around isFold and the
button onClick (the button that navigates to "/credit") to apply these
attributes so keyboard users cannot tab to the hidden control.
- Around line 145-147: The current fold/unfold uses w-auto/h-auto which can't be
animated reliably; update the Lnb component to transition numeric constraints
instead: replace uses of "w-auto" with a numeric max-width (e.g., switch the
class logic that currently toggles between "w-0 opacity-0" and "w-auto
opacity-100" to toggle between "max-w-0 opacity-0" and "max-w-[<px>]
opacity-100") and similarly replace "h-auto" toggles with "max-h-0" vs
"max-h-[<px>]" (or a sufficiently large fixed pixel value) and keep
overflow-hidden and transition-[opacity,max-width] /
transition-[opacity,max-height]; apply the same change for every occurrence of
the transition-[opacity,width] and transition-[opacity,height] class strings in
Lnb.tsx and use the isFold boolean to control max-w/max-h instead of auto so the
animation is smooth and not jumpy.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: beb500e5-ca93-45c1-b9e0-3e58db0ee881

📥 Commits

Reviewing files that changed from the base of the PR and between d47237f and dd24f6f.

⛔ Files ignored due to path filters (4)
  • jobdri/src/assets/ic_Close_S.svg is excluded by !**/*.svg
  • jobdri/src/assets/ic_Email.svg is excluded by !**/*.svg
  • jobdri/src/assets/ic_LOGO_minimum.svg is excluded by !**/*.svg
  • jobdri/src/assets/ic_LOGO_minimum_favi.svg is excluded by !**/*.svg
📒 Files selected for processing (13)
  • jobdri/src/app/page.tsx
  • jobdri/src/components/common/buttons/IconButton.tsx
  • jobdri/src/components/common/buttons/IconOnlyButton.tsx
  • jobdri/src/components/common/footer/BusinessFooter.tsx
  • jobdri/src/components/common/footer/Footer.tsx
  • jobdri/src/components/common/header/Header.tsx
  • jobdri/src/components/common/icons/Icon.tsx
  • jobdri/src/components/common/icons/IconBox.tsx
  • jobdri/src/components/common/input/InputMain.tsx
  • jobdri/src/components/common/lnb/Lnb.tsx
  • jobdri/src/components/common/toast/Toast.tsx
  • jobdri/src/components/login/EmailLoginScreen.tsx
  • jobdri/src/lib/api/questions.ts
💤 Files with no reviewable changes (1)
  • jobdri/src/lib/api/questions.ts

Comment on lines +31 to +35
"flex items-center justify-center gap-2.5 rounded-icon-round bg-bg-white p-2.5",
buttonProps.disabled ? "cursor-not-allowed" : "cursor-pointer",
active ? "text-icon-neutral-heavy" : "text-icon-neutral-assistive",
className,
size === "small" ? "h-6 w-6" : "h-10 w-10",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Small variant sizing is internally inconsistent.

Line 31 keeps fixed p-2.5 and Line 41 keeps a fixed h-6 w-6 icon, while Line 35 can shrink the button to h-6 w-6. The small button ends up with no real content room, so icon rendering/layout is unstable.

Proposed fix
       className={clsx(
-        "flex items-center justify-center gap-2.5 rounded-icon-round bg-bg-white p-2.5",
+        "flex items-center justify-center gap-2.5 rounded-icon-round bg-bg-white",
         buttonProps.disabled ? "cursor-not-allowed" : "cursor-pointer",
         active ? "text-icon-neutral-heavy" : "text-icon-neutral-assistive",
         className,
-        size === "small" ? "h-6 w-6" : "h-10 w-10",
+        size === "small" ? "h-6 w-6 p-1" : "h-10 w-10 p-2",
       )}
       {...buttonProps}
     >
       <Icon
         type={directionIconType[direction]}
-        className="aspect-square h-6 w-6 shrink-0"
+        className={clsx(
+          "aspect-square shrink-0",
+          size === "small" ? "h-4 w-4" : "h-6 w-6",
+        )}
       />

Also applies to: 39-41

🤖 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 `@jobdri/src/components/common/buttons/IconButton.tsx` around lines 31 - 35,
The small variant of IconButton produces inconsistent/insufficient interior
space because padding remains fixed (p-2.5) while the container and icon classes
shrink to h-6 w-6; update IconButton to compute size-aware spacing: when
props.size === "small" set a smaller padding (e.g., p-1 or p-1.5) or
alternatively enforce a minimum container dimension that accommodates the small
icon (adjust the size branch that currently outputs "h-6 w-6"), and ensure the
icon element(s) use a matching small icon class rather than a fixed large icon
size; modify the conditional class list in the IconButton component (the
expression that uses size, className, active, and buttonProps.disabled) so small
uses consistent paired container (height/width) and padding values to prevent
layout collapse.

size = "default",
...buttonProps
}: IconOnlyButtonProps) {
const closeIconType = size === "small" ? "CLOSE_S" : "CLOSE_M";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

iconType is ignored after this change.

Line 42 always renders closeIconType, so callers passing iconType get overridden. This is a behavior regression for a public prop.

Proposed fix
-  const closeIconType = size === "small" ? "CLOSE_S" : "CLOSE_M";
+  const resolvedIconType =
+    size === "small" && iconType === "CLOSE_M" ? "CLOSE_S" : iconType;
@@
-      <Icon
-        type={closeIconType}
-        className={
-          (clsx("shrink-0 "), size === "small" ? "h-5 w-5" : "h-6 w-6")
-        }
-      />
+      <Icon
+        type={resolvedIconType}
+        className={clsx("shrink-0", size === "small" ? "h-5 w-5" : "h-6 w-6")}
+      />

Also applies to: 41-45

🤖 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 `@jobdri/src/components/common/buttons/IconOnlyButton.tsx` at line 27, The
component IconOnlyButton currently computes closeIconType but always passes
closeIconType to the rendered icon (overriding the public prop iconType); update
the render to prefer the prop iconType when provided and fall back to
closeIconType otherwise (e.g., use iconType if truthy, else closeIconType) so
callers' iconType values are respected; look for the computed constant
closeIconType and the prop iconType in the IconOnlyButton component and change
the value used in the JSX where the icon is rendered.

Comment on lines +145 to +147
className={`overflow-hidden whitespace-nowrap transition-[opacity,width] duration-150 ${
isFold ? "w-0 opacity-0" : "w-auto opacity-100"
}`}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Can CSS transitions animate width/height when one state is auto? What are recommended alternatives (max-width/max-height, transform, grid) for smooth collapse animations?

💡 Result:

Yes—within current CSS specifications and browser implementations, transitions/animations generally should not rely on a state change where one endpoint is auto (e.g., height: 0height: auto). MDN notes that the specification recommends not animating from and to auto, and that behavior can be unpredictable across engines [1]. Chrome’s docs similarly frame the problem as “animate to intrinsic sizing keywords like auto” being non-trivial, and introduce newer opt-in mechanisms [2]. Recommended alternatives for smooth collapse/expand animations 1) Use max-height / max-width (classic workaround) Animate a numeric ceiling instead of auto: e.g., max-height: 0max-height: <big enough>, with overflow: hidden. This is the commonly cited “cannot animate height to auto directly” workaround [3][4]. 2) Use CSS Grid row animation (0fr → 1fr) A grid-based approach animates grid-template-rows between 0fr (collapsed) and 1fr (expanded), so the grid row can take the content’s intrinsic size without needing auto in the transition itself [5][6]. A widely referenced implementation is:.expander { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.5s ease; }.expander.expanded { grid-template-rows: 1fr; } (and pair with overflow: hidden on the inner content if needed) [6]. 3) Prefer transform/opacity when possible For many UI elements, switching to transform (and opacity) avoids layout-driven properties. General guidance is to animate transform/opacity rather than width/height for performance/smoothness, because width/height are layout-affecting [7]. 4) If you specifically need height/width + “intrinsic” end state: opt into intrinsic-size interpolation (newer CSS) Chrome documents a newer mechanism that enables transitions/animations to intrinsic sizing keywords by using interpolate-size (opt-in) [2]. Example::root { interpolate-size: allow-keywords; } Then an element can transition to height: auto (in browsers with support) [2]. Additionally, the same theme shows up via calc-size() (math around intrinsic sizing keywords) as another route to animating to/from auto in browsers that implement it [8][9]. 5) For “first paint” / display toggles: use transition start controls When collapsing/expanding with display: none/showing, you typically need @starting-style and transition-behavior: allow-discrete to ensure transitions start on the first style update. MDN’s transition guide shows @starting-style and allow-discrete usage when transitioning display and establishing a before-start style [1]. Practical rule of thumb - If you need a CSS-only solution today: use max-height/max-width or the grid-template-rows technique [3][6]. - If you can use non-size animations: use transform/opacity [7]. - If you truly need auto-exact sizing and can target modern Chromium (or browsers with support): consider interpolate-size: allow-keywords (and/or calc-size()) [2][8]. If you tell me your target browsers (Chrome/Firefox/Safari versions) and whether you’re animating a dropdown, accordion, or side panel, I can recommend the best concrete pattern and code.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show relevant sections around the referenced lines
sed -n '120,220p' jobdri/src/components/common/lnb/Lnb.tsx | nl -ba

# Search for other fold/unfold className patterns in this file
rg -n "transition-\\[opacity,(width|height)\\]|w-auto|h-auto|max-w-|max-h-|transition-\\[opacity,max-(width|height)\\]|interpolate-size|calc-size\\(" jobdri/src/components/common/lnb/Lnb.tsx

# Search repo for interpolate-size usage
rg -n "interpolate-size|calc-size\\(" -S .

Repository: JobDri-Developer/FrontEnd

Length of output: 112


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '120,220p' jobdri/src/components/common/lnb/Lnb.tsx | nl -ba

rg -n "transition-\\[opacity,(width|height)\\]|w-auto|h-auto|max-w-|max-h-|transition-\\[opacity,max-(width|height)\\]|interpolate-size|calc-size\\(" jobdri/src/components/common/lnb/Lnb.tsx

rg -n "interpolate-size|calc-size\\(" -S .

Repository: JobDri-Developer/FrontEnd

Length of output: 112


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show relevant sections around the referenced lines
sed -n '120,220p' jobdri/src/components/common/lnb/Lnb.tsx | nl -ba

# Search for other fold/unfold className patterns in this file
rg -n "transition-\\[opacity,(width|height)\\]|w-auto|h-auto|max-w-|max-h-|transition-\\[opacity,max-(width|height)\\]|interpolate-size|calc-size\\(" jobdri/src/components/common/lnb/Lnb.tsx

# Search repo for interpolate-size usage
rg -n "interpolate-size|calc-size\\(" -S .

Repository: JobDri-Developer/FrontEnd

Length of output: 112


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="jobdri/src/components/common/lnb/Lnb.tsx"

echo "=== Lnb.tsx excerpt (lines 120-220) ==="
# Use cat -n to provide line numbers (since nl isn't available)
sed -n '120,220p' "$FILE" | cat -n

echo
echo "=== rg hits in Lnb.tsx ==="
rg -n "w-auto|h-auto|transition-\\[opacity,(width|height)\\]|transition-\\[opacity,max-(width|height)\\]|max-w-|max-h-|transition-\\[opacity,width\\]|transition-\\[opacity,height\\]" "$FILE" || true

echo
echo "=== rg hits for interpolate-size/calc-size across repo ==="
rg -n "interpolate-size|calc-size\\(" -S . || true

Repository: JobDri-Developer/FrontEnd

Length of output: 5457


Avoid auto endpoints in fold/unfold width/height transitions to prevent abrupt animation

  • Lnb.tsx transitions w-auto/h-auto in transition-[opacity,width] and transition-[opacity,height] (lines 145-147, 159-161, and 195-197). Transitions to/from auto aren’t reliably animatable, so the fold/unfold will jump.
  • Replace w-auto/h-auto with animatable numeric constraints (e.g., max-width/max-height with overflow-hidden using sufficiently large bounds), or use a grid-row (grid-template-rows) / transform-based approach.
🤖 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 `@jobdri/src/components/common/lnb/Lnb.tsx` around lines 145 - 147, The current
fold/unfold uses w-auto/h-auto which can't be animated reliably; update the Lnb
component to transition numeric constraints instead: replace uses of "w-auto"
with a numeric max-width (e.g., switch the class logic that currently toggles
between "w-0 opacity-0" and "w-auto opacity-100" to toggle between "max-w-0
opacity-0" and "max-w-[<px>] opacity-100") and similarly replace "h-auto"
toggles with "max-h-0" vs "max-h-[<px>]" (or a sufficiently large fixed pixel
value) and keep overflow-hidden and transition-[opacity,max-width] /
transition-[opacity,max-height]; apply the same change for every occurrence of
the transition-[opacity,width] and transition-[opacity,height] class strings in
Lnb.tsx and use the isFold boolean to control max-w/max-h instead of auto so the
animation is smooth and not jumpy.

Comment on lines +158 to +174
<div
className={`overflow-hidden transition-[opacity,height] duration-150 w-full ${
isFold ? "h-0 opacity-0" : "h-auto opacity-100"
}`}
>
<div className="flex w-full items-center justify-between px-2 py-2">
<button
type="button"
onClick={() => router.push("/credit")}
className="flex items-center gap-[3px] text-label14-med text-icon-neutral-default [font-feature-settings:'liga'_off,'clig'_off] hover:text-text-neutral-title"
>
<span>크레딧</span>
<Icon
type="EX_LINK"
className="h-4 w-4 text-icon-neutral-assistive"
/>
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Hidden credit action remains focusable when folded.

On folded state, the credit section is visually hidden but still mounted and interactive. Keyboard users can tab to an invisible button (Line 164), which is an accessibility bug.

Suggested fix
-          <div
-            className={`overflow-hidden transition-[opacity,height] duration-150 w-full ${
-              isFold ? "h-0 opacity-0" : "h-auto opacity-100"
-            }`}
-          >
+          <div
+            aria-hidden={isFold}
+            className={`overflow-hidden transition-[opacity,max-height] duration-150 w-full ${
+              isFold ? "max-h-0 opacity-0 pointer-events-none" : "max-h-24 opacity-100"
+            }`}
+          >
             <div className="flex w-full items-center justify-between px-2 py-2">
               <button
                 type="button"
+                tabIndex={isFold ? -1 : 0}
                 onClick={() => router.push("/credit")}
                 className="flex items-center gap-[3px] text-label14-med text-icon-neutral-default [font-feature-settings:'liga'_off,'clig'_off] hover:text-text-neutral-title"
               >
📝 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
<div
className={`overflow-hidden transition-[opacity,height] duration-150 w-full ${
isFold ? "h-0 opacity-0" : "h-auto opacity-100"
}`}
>
<div className="flex w-full items-center justify-between px-2 py-2">
<button
type="button"
onClick={() => router.push("/credit")}
className="flex items-center gap-[3px] text-label14-med text-icon-neutral-default [font-feature-settings:'liga'_off,'clig'_off] hover:text-text-neutral-title"
>
<span>크레딧</span>
<Icon
type="EX_LINK"
className="h-4 w-4 text-icon-neutral-assistive"
/>
</button>
<div
aria-hidden={isFold}
className={`overflow-hidden transition-[opacity,max-height] duration-150 w-full ${
isFold ? "max-h-0 opacity-0 pointer-events-none" : "max-h-24 opacity-100"
}`}
>
<div className="flex w-full items-center justify-between px-2 py-2">
<button
type="button"
tabIndex={isFold ? -1 : 0}
onClick={() => router.push("/credit")}
className="flex items-center gap-[3px] text-label14-med text-icon-neutral-default [font-feature-settings:'liga'_off,'clig'_off] hover:text-text-neutral-title"
>
<span>크레딧</span>
<Icon
type="EX_LINK"
className="h-4 w-4 text-icon-neutral-assistive"
/>
</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 `@jobdri/src/components/common/lnb/Lnb.tsx` around lines 158 - 174, The credit
button remains focusable when the LNB is folded; update the folded branch to
make hidden controls non-interactive by adding aria-hidden={isFold} to the
toggle container and make the button unfocusable when folded (e.g., set
tabIndex={isFold ? -1 : 0} and aria-hidden={isFold} on the <button> in the block
that contains isFold), or alternatively render null when folded; target the JSX
around isFold and the button onClick (the button that navigates to "/credit") to
apply these attributes so keyboard users cannot tab to the hidden control.

@yiyoonseo yiyoonseo merged commit ea8a5bc into develop May 22, 2026
1 check passed
@yiyoonseo yiyoonseo deleted the feature/#64-compnent-feat branch May 22, 2026 19:53
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.

Feat: 컴포넌트 추가 개발 및 수정

2 participants