Skip to content

[Feat] #11 - 공통 InputBox 컴포넌트 추가#15

Merged
sebeeeen merged 6 commits into
devfrom
feat/shared-inputbox
Mar 4, 2026
Merged

[Feat] #11 - 공통 InputBox 컴포넌트 추가#15
sebeeeen merged 6 commits into
devfrom
feat/shared-inputbox

Conversation

@jaeu5325
Copy link
Copy Markdown
Collaborator

@jaeu5325 jaeu5325 commented Feb 2, 2026

🔎 What is this PR?

공통 inputBox 컴포넌트를 구현하고 Storybook 문서화를 완료


📝 Changes

  1. InputBox 컴포넌트
  • 컨벤션 적용: Button 컴포넌트와 동일한 스타일 상수 분리 및 헬퍼 함수 구조 적용
  • Props 네이밍 변경: fullWidth → isFullWidth, error → hasError로 표준화
  • 서브 컴포넌트 통합: Input, Textarea, Select 컴포넌트의 공통 스타일 로직 통합 관리
  1. Storybook
  • 스토리 세분화: Default, WithIcons, Password(강도 표시), Search, ErrorState 등 사용 케이스별 스토리 분리
  • 문서화 강화: Controls 패널 연동 및 상태 모아보기(States) 스토리 추가
  1. 아이콘 추가
  • LockIcon 추가: 비밀번호 입력 필드에 사용되는 자물쇠 아이콘 정의

📸 Screenshots (선택)

스크린샷 2026-02-02 오전 10 02 17 스크린샷 2026-02-02 오전 10 02 39 스크린샷 2026-02-02 오전 10 02 54 스크린샷 2026-02-02 오전 10 03 08 스크린샷 2026-02-02 오전 10 03 23 스크린샷 2026-02-02 오전 10 03 34 스크린샷 2026-02-02 오전 10 03 44 스크린샷 2026-02-02 오전 10 04 23

🔗 Related Issue

closes #11


✔ Checklist

  • 코드는 로컬에서 정상적으로 빌드됩니다 (pnpm build)
  • ESLint / Prettier 통과 (pnpm lint)
  • 네이밍/레이어 컨벤션 준수 (camelCase/PascalCase, is·has 불린 접두사, alias 계층 규칙)
  • 관련 문서/주석 반영 (필요 시)
  • 주요 로직에 테스트 또는 검증 완료

🙏 Request

리뷰 요청 파일

  1. src/shared/ui/inputBox/inputBox.tsx
  2. src/shared/ui/inputBox/inputBox.stories.tsx
  3. src/shared/ui/icons.tsx

Summary by CodeRabbit

  • New Features

    • Added seven UI icons (eye, eye-off, chevron-down, x-circle, user, mail, lock).
    • Introduced unified Input, Textarea, and Select controls with icon support, password visibility toggle, search/clear, password-strength, character limits, placeholders/options, and consistent visual states.
    • Added Storybook stories demonstrating input variants, interactions, and states.
  • Chores

    • Removed GitHub issue templates for bug reports and feature requests.

@jaeu5325 jaeu5325 requested a review from sebeeeen February 2, 2026 01:53
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

Adds a shared InputBox module (Input, Textarea, Select) with styling helpers, expands the icon library with seven SVG icons, adds Storybook stories for InputBox variants, and removes two GitHub issue templates.

Changes

Cohort / File(s) Summary
Issue Templates Removal
​.github/ISSUE_TEMPLATE/bug_report.md, ​.github/ISSUE_TEMPLATE/feature_request.md
Removed two GitHub issue templates (bug report and feature request) previously authored in Korean.
Icon Library Expansion
src/shared/ui/icons/index.tsx
Added seven exported SVG icon components: EyeIcon, EyeOffIcon, ChevronDownIcon, XCircleIcon, UserIcon, MailIcon, LockIcon.
InputBox Implementation
src/shared/ui/inputBox/inputBox.tsx
Introduced Input, Textarea, and Select components and their prop interfaces (InputProps, TextareaProps, SelectProps); centralized class/style helpers; support for sizes, full-width, left/right icons, password visibility toggle, search clear, password strength indicator, char count, placeholder handling, and error/focus states.
InputBox Stories
src/shared/ui/inputBox/inputBox.stories.tsx
Added Storybook stories demonstrating variants: Default, WithIcons, Password, Search, ErrorState, TextareaField, SelectField, and States, using the new icons and component props.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble keys and craft a line,
I hide and peek with eyes that shine,
A chevron hop, a circle clear,
Mail and lock bring comfort near,
New fields sprout — I thump with cheer.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: adding a shared InputBox component, which aligns with the primary objective.
Description check ✅ Passed The PR description includes the required sections: What is this PR, Changes, Screenshots, Related Issue, and Checklist, providing comprehensive documentation of the implementation.
Linked Issues check ✅ Passed The PR implements all core requirements from issue #11: InputBox component with Input/Textarea/Select subcomponents, comprehensive Storybook stories with multiple use cases, and new icon exports (EyeIcon, EyeOffIcon, ChevronDownIcon, XCircleIcon, UserIcon, MailIcon, LockIcon).
Out of Scope Changes check ✅ Passed All changes are directly related to issue #11 objectives: InputBox component implementation, Storybook documentation, icon additions, and removal of outdated issue templates. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/shared-inputbox

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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 and usage tips.

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In `@src/shared/ui/inputBox/inputBox.tsx`:
- Around line 195-213: The icon-only buttons in inputBox.tsx lack accessible
labels; add aria-label attributes to the password toggle button (the button that
calls setIsPasswordVisible and renders EyeIcon/EyeOffIcon) and to the search
clear button (the button that calls onClear and renders XCircleIcon), using
descriptive text such as "Show password"/"Hide password" based on
isPasswordVisible for the password toggle and "Clear search" for the clear
button; ensure the labels are present only when the buttons render (type ===
"password" && !disabled and isSearch && props.value && onClear) so screen
readers receive meaningful descriptions.
- Around line 25-27: The Tailwind v4 breaking change means the important
modifier must be suffixed not prefixed, so update the class strings in the
inputBox export (the "error" and any similar class constants like
"defaultBorder") to move leading "!" to the end of the utility — e.g., change
instances like "!border-[color:var(--color-error-500,...)]" to
"border-[color:var(--color-error-500,...)]!" and "focus:!shadow-[...]" to
"focus:shadow-[...]!" so the important modifier is a trailing suffix on the
utility classes used in inputBox.tsx.
- Around line 251-280: The charCount state in the Textarea component doesn't
initialize or sync with incoming defaultValue/value, so set its initial state
from props (e.g., useState(() => ((props.value ?? props.defaultValue) as string
|| '').length)) and add a useEffect that updates charCount whenever props.value
or props.defaultValue changes; keep handleChange as-is to update on user input.
Ensure you reference the forwarded component Textarea, state variable charCount,
handler handleChange, and the incoming props (value/defaultValue/maxLength) when
implementing the initialization and sync.

Comment thread src/shared/ui/inputBox/inputBox.tsx Outdated
Comment on lines +195 to +213
{type === "password" && !disabled && (
<button
type="button"
onClick={() => setIsPasswordVisible(!isPasswordVisible)}
className="text-[color:var(--color-gray-600,#666666)] hover:text-[color:var(--color-primary-800,#004A9C)] focus:outline-none"
>
{isPasswordVisible ? <EyeOffIcon width={20} /> : <EyeIcon width={20} />}
</button>
)}

{isSearch && props.value && onClear && (
<button
type="button"
onClick={onClear}
className="text-[color:var(--color-gray-600,#666666)] hover:text-[color:var(--color-gray-900,#1A1A1A)] focus:outline-none"
>
<XCircleIcon width={16} />
</button>
)}
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.

⚠️ Potential issue | 🟡 Minor

Add aria-labels for accessibility on icon buttons.

The password visibility toggle and search clear buttons lack accessible labels. Screen reader users won't understand what these buttons do.

♿ Proposed fix for accessibility
             {type === "password" && !disabled && (
               <button
                 type="button"
                 onClick={() => setIsPasswordVisible(!isPasswordVisible)}
+                aria-label={isPasswordVisible ? "비밀번호 숨기기" : "비밀번호 보기"}
                 className="text-[color:var(--color-gray-600,`#666666`)] hover:text-[color:var(--color-primary-800,`#004A9C`)] focus:outline-none"
               >
                 {isPasswordVisible ? <EyeOffIcon width={20} /> : <EyeIcon width={20} />}
               </button>
             )}

             {isSearch && props.value && onClear && (
               <button
                 type="button"
                 onClick={onClear}
+                aria-label="검색어 지우기"
                 className="text-[color:var(--color-gray-600,`#666666`)] hover:text-[color:var(--color-gray-900,`#1A1A1A`)] focus:outline-none"
               >
                 <XCircleIcon width={16} />
               </button>
             )}
📝 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
{type === "password" && !disabled && (
<button
type="button"
onClick={() => setIsPasswordVisible(!isPasswordVisible)}
className="text-[color:var(--color-gray-600,#666666)] hover:text-[color:var(--color-primary-800,#004A9C)] focus:outline-none"
>
{isPasswordVisible ? <EyeOffIcon width={20} /> : <EyeIcon width={20} />}
</button>
)}
{isSearch && props.value && onClear && (
<button
type="button"
onClick={onClear}
className="text-[color:var(--color-gray-600,#666666)] hover:text-[color:var(--color-gray-900,#1A1A1A)] focus:outline-none"
>
<XCircleIcon width={16} />
</button>
)}
{type === "password" && !disabled && (
<button
type="button"
onClick={() => setIsPasswordVisible(!isPasswordVisible)}
aria-label={isPasswordVisible ? "비밀번호 숨기기" : "비밀번호 보기"}
className="text-[color:var(--color-gray-600,`#666666`)] hover:text-[color:var(--color-primary-800,`#004A9C`)] focus:outline-none"
>
{isPasswordVisible ? <EyeOffIcon width={20} /> : <EyeIcon width={20} />}
</button>
)}
{isSearch && props.value && onClear && (
<button
type="button"
onClick={onClear}
aria-label="검색어 지우기"
className="text-[color:var(--color-gray-600,`#666666`)] hover:text-[color:var(--color-gray-900,`#1A1A1A`)] focus:outline-none"
>
<XCircleIcon width={16} />
</button>
)}
🤖 Prompt for AI Agents
In `@src/shared/ui/inputBox/inputBox.tsx` around lines 195 - 213, The icon-only
buttons in inputBox.tsx lack accessible labels; add aria-label attributes to the
password toggle button (the button that calls setIsPasswordVisible and renders
EyeIcon/EyeOffIcon) and to the search clear button (the button that calls
onClear and renders XCircleIcon), using descriptive text such as "Show
password"/"Hide password" based on isPasswordVisible for the password toggle and
"Clear search" for the clear button; ensure the labels are present only when the
buttons render (type === "password" && !disabled and isSearch && props.value &&
onClear) so screen readers receive meaningful descriptions.

Comment thread src/shared/ui/inputBox/inputBox.tsx
Copy link
Copy Markdown
Member

@sebeeeen sebeeeen left a comment

Choose a reason for hiding this comment

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

수고많으셨어용 🚀

Comment thread src/shared/ui/inputBox/inputBox.tsx Outdated
Comment thread src/shared/ui/inputBox/inputBox.stories.tsx Outdated
@sebeeeen
Copy link
Copy Markdown
Member

sebeeeen commented Feb 2, 2026

PR제목도 컨벤션 맞춰서 수정 부탁드려요~

@jaeu5325 jaeu5325 changed the title #11 - 공통 inputBox 컴포넌트 추가 [Feat] #11 - 공통 inputBox 컴포넌트 추가 Feb 2, 2026
Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In `@src/shared/ui/inputBox/inputBox.stories.tsx`:
- Around line 80-90: The Search story provides onClear but doesn't set a value
so the clear button won't render; update the Search Story (export const Search)
to include a non-empty value (or defaultValue) in args (e.g., value: "example")
so the component's condition that checks props.value && onClear becomes truthy
and the clear button is visible; keep the existing onClear handler to
demonstrate the clear behavior.

In `@src/shared/ui/inputBox/inputBox.tsx`:
- Around line 71-89: getTextareaClasses is missing support for the disabled
visual state—add a disabled boolean parameter (matching
getInputClasses/getSelectClasses signature), compute a disabledClass variable
that uses commonStyles.disabled when disabled is true, and include that
disabledClass in the returned class list (ensuring it is applied alongside/after
stateClass so disabled styling takes precedence). Update any call sites that
render <textarea> to pass the disabled flag where appropriate.
🧹 Nitpick comments (1)
src/shared/ui/inputBox/inputBox.tsx (1)

283-314: Potential controlled/uncontrolled conflict in Select.

When placeholder is provided, defaultValue="" is set unconditionally. If a consumer also passes a value prop (controlled mode), React may warn about switching between controlled and uncontrolled states, or the defaultValue becomes ineffective.

Consider conditionally applying defaultValue only when not in controlled mode:

🔧 Proposed fix
       <select
         ref={ref}
         className={selectClasses}
-        defaultValue={placeholder ? "" : undefined}
+        defaultValue={placeholder && props.value === undefined ? "" : undefined}
         {...props}
       >

Comment on lines +80 to +90
// 검색 입력 (Rounded Pill Shape)
export const Search: Story = {
args: {
type: "search",
placeholder: "검색어를 입력하세요...",
size: "medium",
isFullWidth: true,
// onClear가 전달되면 값이 있을 때 X 버튼이 자동으로 노출됨
onClear: () => alert("Clear Clicked!"),
},
};
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.

⚠️ Potential issue | 🟡 Minor

Clear button won't be visible without a value prop.

The onClear callback is provided but the clear button only renders when props.value && onClear is truthy (per component logic at line 188 in inputBox.tsx). Without a value, users won't see the clear functionality in this story.

🔧 Proposed fix to demonstrate clear functionality
 export const Search: Story = {
   args: {
     type: "search",
     placeholder: "검색어를 입력하세요...",
     size: "medium",
     isFullWidth: true,
+    value: "검색어 예시",
     // onClear가 전달되면 값이 있을 때 X 버튼이 자동으로 노출됨
     onClear: () => alert("Clear Clicked!"),
   },
 };
📝 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
// 검색 입력 (Rounded Pill Shape)
export const Search: Story = {
args: {
type: "search",
placeholder: "검색어를 입력하세요...",
size: "medium",
isFullWidth: true,
// onClear가 전달되면 값이 있을 때 X 버튼이 자동으로 노출됨
onClear: () => alert("Clear Clicked!"),
},
};
// 검색 입력 (Rounded Pill Shape)
export const Search: Story = {
args: {
type: "search",
placeholder: "검색어를 입력하세요...",
size: "medium",
isFullWidth: true,
value: "검색어 예시",
// onClear가 전달되면 값이 있을 때 X 버튼이 자동으로 노출됨
onClear: () => alert("Clear Clicked!"),
},
};
🤖 Prompt for AI Agents
In `@src/shared/ui/inputBox/inputBox.stories.tsx` around lines 80 - 90, The Search
story provides onClear but doesn't set a value so the clear button won't render;
update the Search Story (export const Search) to include a non-empty value (or
defaultValue) in args (e.g., value: "example") so the component's condition that
checks props.value && onClear becomes truthy and the clear button is visible;
keep the existing onClear handler to demonstrate the clear behavior.

Comment on lines +71 to +89
const getTextareaClasses = (
hasError: boolean,
isFullWidth: boolean,
className?: string,
): string => {
const stateClass = hasError ? commonStyles.error : commonStyles.defaultBorder;
const widthClass = isFullWidth ? "w-full" : "w-auto";

return [
commonStyles.base,
"min-h-[120px] p-3 text-[16px] leading-[24px] rounded-lg bg-white resize-y",
commonStyles.focus,
stateClass,
widthClass,
className,
]
.filter(Boolean)
.join(" ");
};
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.

⚠️ Potential issue | 🟡 Minor

Missing disabled styling for Textarea.

getTextareaClasses doesn't include commonStyles.disabled, unlike getInputClasses (line 58) and getSelectClasses (line 97). Disabled textareas will lack the proper visual feedback.

🐛 Proposed fix to add disabled styles
 const getTextareaClasses = (
   hasError: boolean,
   isFullWidth: boolean,
   className?: string,
 ): string => {
   const stateClass = hasError ? commonStyles.error : commonStyles.defaultBorder;
   const widthClass = isFullWidth ? "w-full" : "w-auto";

   return [
     commonStyles.base,
+    commonStyles.disabled,
     "min-h-[120px] p-3 text-[16px] leading-[24px] rounded-lg bg-white resize-y",
     commonStyles.focus,
     stateClass,
     widthClass,
     className,
   ]
     .filter(Boolean)
     .join(" ");
 };
🤖 Prompt for AI Agents
In `@src/shared/ui/inputBox/inputBox.tsx` around lines 71 - 89, getTextareaClasses
is missing support for the disabled visual state—add a disabled boolean
parameter (matching getInputClasses/getSelectClasses signature), compute a
disabledClass variable that uses commonStyles.disabled when disabled is true,
and include that disabledClass in the returned class list (ensuring it is
applied alongside/after stateClass so disabled styling takes precedence). Update
any call sites that render <textarea> to pass the disabled flag where
appropriate.

@sebeeeen sebeeeen self-requested a review February 3, 2026 05:52
sebeeeen
sebeeeen previously approved these changes Feb 3, 2026
Copy link
Copy Markdown
Member

@sebeeeen sebeeeen left a comment

Choose a reason for hiding this comment

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

수고하셨습니다~

@sebeeeen sebeeeen changed the title [Feat] #11 - 공통 inputBox 컴포넌트 추가 [Feat] #11 - 공통 InputBox 컴포넌트 추가 Feb 3, 2026
@sebeeeen sebeeeen requested a review from Copilot February 6, 2026 12:28

This comment was marked as duplicate.

Copy link
Copy Markdown
Contributor

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/shared/ui/inputBox/inputBox.tsx`:
- Line 194: The XCircleIcon is passed width={16} which only overrides the SVG
width, leaving height at the default 20; change the usage in inputBox.tsx to
pass size={16} (or set both width and height to 16) so the icon renders square.
Locate the instance of XCircleIcon in the InputBox component (symbol:
XCircleIcon) and replace width={16} with size={16} (or width={16} height={16})
to ensure both dimensions match.
- Around line 140-142: The computed boolean hasRightContent incorrectly includes
password buttons even when the input is disabled; update the expression that
sets hasRightContent to only count the password toggle when the input is not
disabled (e.g., change the password check from type === "password" to type ===
"password" && !disabled) so rightIcon, isSearch && props.value && onClear, and
the password toggle (guarded by disabled) are consistently reflected by
hasRightContent; adjust the expression where hasRightContent is declared to
reference the existing symbols (rightIcon, type, isSearch, props.value, onClear,
disabled) accordingly.
- Around line 283-294: The Select component currently always sets
defaultValue="" when placeholder is present which, when combined with a
consumer-supplied value prop, causes React's controlled/uncontrolled warning;
fix this in Select by computing and applying value-related props conditionally:
inspect props for existing "value" or "defaultValue" and if either exists do not
set a defaultValue, otherwise if placeholder is provided set defaultValue to ""
(or leave undefined when no placeholder); then spread these computed value props
and finally spread the remaining {...props} into the <select> so you never end
up with both a consumer "value" and an internal defaultValue.

---

Duplicate comments:
In `@src/shared/ui/inputBox/inputBox.tsx`:
- Around line 178-196: Add accessible labels to the icon-only buttons: for the
password toggle in the block using setIsPasswordVisible and isPasswordVisible
(and rendering EyeIcon/EyeOffIcon) add a dynamic aria-label that reads "Show
password" when isPasswordVisible is false and "Hide password" when true, and
also include aria-pressed={isPasswordVisible} to convey toggle state; for the
search clear button that uses isSearch, props.value and onClear (rendering
XCircleIcon) add an aria-label="Clear search" so screen readers can identify the
control. Ensure the attributes are present on the same <button> elements already
using type="button".
- Around line 71-89: getTextareaClasses is missing support for disabled styling;
update its signature to accept an isDisabled boolean (e.g.,
getTextareaClasses(hasError, isFullWidth, isDisabled, className)), compute a
disabledClass = isDisabled ? commonStyles.disabled : null, and when isDisabled
is true use disabledClass in place of the error/default state (i.e., don't apply
stateClass when disabled). Add disabledClass into the returned classes array
alongside commonStyles.base, commonStyles.focus, widthClass, etc., then filter
and join as before so disabled textareas render the same visual state as
Input/Select.
- Around line 18-19: commonStyles.error uses Tailwind v3-style leading "!"
modifiers which are invalid in Tailwind v4; update the utilities so the
important marker is a trailing suffix instead. Replace
"!border-[color:var(--color-error-500,`#EF4444`)]" with
"border-[color:var(--color-error-500,`#EF4444`)]!" and replace
"focus:!shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]" with
"focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!" in the
commonStyles.error definition in inputBox.tsx so the important modifier follows
Tailwind v4 syntax.

Comment on lines +140 to +142
const hasRightContent = Boolean(
rightIcon || type === "password" || (isSearch && props.value && onClear),
);
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.

⚠️ Potential issue | 🟡 Minor

hasRightContent incorrectly adds right padding for disabled password inputs.

type === "password" is unconditionally true, so right padding is always applied. However, the password toggle button is guarded by !disabled (Line 178), so no icon is rendered—leaving the input with spurious right padding when disabled.

🐛 Proposed fix
  const hasRightContent = Boolean(
-   rightIcon || type === "password" || (isSearch && props.value && onClear),
+   rightIcon || (type === "password" && !disabled) || (isSearch && props.value && onClear),
  );
📝 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 hasRightContent = Boolean(
rightIcon || type === "password" || (isSearch && props.value && onClear),
);
const hasRightContent = Boolean(
rightIcon || (type === "password" && !disabled) || (isSearch && props.value && onClear),
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 140 - 142, The computed
boolean hasRightContent incorrectly includes password buttons even when the
input is disabled; update the expression that sets hasRightContent to only count
the password toggle when the input is not disabled (e.g., change the password
check from type === "password" to type === "password" && !disabled) so
rightIcon, isSearch && props.value && onClear, and the password toggle (guarded
by disabled) are consistently reflected by hasRightContent; adjust the
expression where hasRightContent is declared to reference the existing symbols
(rightIcon, type, isSearch, props.value, onClear, disabled) accordingly.

onClick={onClear}
className="text-[color:var(--color-gray-600,#666666)] hover:text-[color:var(--color-gray-900,#1A1A1A)] focus:outline-none"
>
<XCircleIcon width={16} />
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.

⚠️ Potential issue | 🟡 Minor

<XCircleIcon width={16} /> renders non-square (16 × 20).

Icon components use { size = 20, ...props } with width={size} and height={size} on the SVG, followed by {...props}. Passing width={16} overrides only width, leaving height at its default of 20. Use size instead:

🐛 Proposed fix
-              <XCircleIcon width={16} />
+              <XCircleIcon size={16} />
📝 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
<XCircleIcon width={16} />
<XCircleIcon size={16} />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` at line 194, The XCircleIcon is passed
width={16} which only overrides the SVG width, leaving height at the default 20;
change the usage in inputBox.tsx to pass size={16} (or set both width and height
to 16) so the icon renders square. Locate the instance of XCircleIcon in the
InputBox component (symbol: XCircleIcon) and replace width={16} with size={16}
(or width={16} height={16}) to ensure both dimensions match.

Comment on lines +283 to +294
export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
({ hasError, isFullWidth = true, options, placeholder, className = "", ...props }, ref) => {
const selectClasses = getSelectClasses(!!hasError, !!isFullWidth, className);
const containerClasses = `relative ${isFullWidth ? "w-full" : "w-auto"}`;

return (
<div className={containerClasses}>
<select
ref={ref}
className={selectClasses}
defaultValue={placeholder ? "" : undefined}
{...props}
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.

⚠️ Potential issue | 🟡 Minor

Select emits a React warning when used as a controlled component with a placeholder.

Setting defaultValue="" before spreading {...props} means a consumer who passes value ends up with both value and defaultValue on the underlying <select>, triggering React's controlled/uncontrolled mixing warning.

🐛 Proposed fix
  export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
-   ({ hasError, isFullWidth = true, options, placeholder, className = "", ...props }, ref) => {
+   ({ hasError, isFullWidth = true, options, placeholder, className = "", value, ...props }, ref) => {
    const selectClasses = getSelectClasses(!!hasError, !!isFullWidth, className);
    const containerClasses = `relative ${isFullWidth ? "w-full" : "w-auto"}`;

    return (
      <div className={containerClasses}>
        <select
          ref={ref}
          className={selectClasses}
-         defaultValue={placeholder ? "" : undefined}
-         {...props}
+         value={value}
+         {...(value === undefined ? { defaultValue: placeholder ? "" : undefined } : {})}
+         {...props}
        >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 283 - 294, The Select
component currently always sets defaultValue="" when placeholder is present
which, when combined with a consumer-supplied value prop, causes React's
controlled/uncontrolled warning; fix this in Select by computing and applying
value-related props conditionally: inspect props for existing "value" or
"defaultValue" and if either exists do not set a defaultValue, otherwise if
placeholder is provided set defaultValue to "" (or leave undefined when no
placeholder); then spread these computed value props and finally spread the
remaining {...props} into the <select> so you never end up with both a consumer
"value" and an internal defaultValue.

@jaeu5325 jaeu5325 closed this Feb 18, 2026
@jaeu5325 jaeu5325 reopened this Feb 18, 2026
@sebeeeen sebeeeen self-requested a review February 19, 2026 00:07
Comment thread package-lock.json Outdated
Comment thread src/shared/ui/inputBox/inputBox.tsx Outdated
@jaeu5325 jaeu5325 requested a review from sebeeeen February 20, 2026 03:07
@jaeu5325 jaeu5325 force-pushed the feat/shared-inputbox branch from dd8a233 to b65c8f5 Compare February 25, 2026 12:32
sebeeeen
sebeeeen previously approved these changes Feb 25, 2026
Copy link
Copy Markdown
Member

@sebeeeen sebeeeen left a comment

Choose a reason for hiding this comment

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

수고하셨습니다~ 충돌 오류만 해결해주세요~!

Copy link
Copy Markdown
Contributor

@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 (10)
src/shared/ui/inputBox/inputBox.tsx (10)

195-195: <XCircleIcon width={16} /> still renders non-square (16 × 20).

The icon spreads {...props} after the explicit height={size} on the SVG element, so passing width={16} only overrides width while height remains at the default 20. Use size={16} to set both dimensions uniformly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` at line 195, The XCircleIcon is rendered
non-square because inputBox.tsx passes width={16} and the component spreads
{...props} after height={size}, so height stays 20; update the usage in
inputBox.tsx to pass size={16} (not width) when rendering <XCircleIcon> so both
width and height are set uniformly by the icon component.

141-143: hasRightContent still incorrectly adds right padding for disabled password inputs.

type === "password" is unconditionally included, but the password toggle button is guarded by !disabled (Line 179). A disabled password <Input> will receive spurious right padding with no icon to fill it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 141 - 143, The
hasRightContent calculation adds padding for password fields even when disabled;
update the Boolean expression used to compute hasRightContent (the const
hasRightContent) to only include the password case when the input is not
disabled (i.e., include a !disabled guard alongside type === "password"); keep
the existing checks for rightIcon, isSearch && props.value && onClear unchanged
so the password toggle padding is only applied when the password toggle button
will actually render.

195-195: <XCircleIcon width={16} /> still renders non-square (16 × 20).

The icon API spreads {...props} after height={size}, so only width is overridden to 16 while height stays at the default 20. Use size={16} to set both dimensions uniformly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` at line 195, The XCircleIcon is being
rendered non-square because width={16} overrides only width while the
component's props set height after, so change the usage in inputBox.tsx from
passing width={16} to using size={16} on the XCircleIcon component to ensure
both width and height are set to 16 (locate the XCircleIcon JSX in the
inputBox.tsx file).

179-196: Password toggle and clear buttons still lack aria-label.

Both icon-only buttons remain without accessible labels, leaving screen-reader users unable to identify their purpose.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 179 - 196, Add accessible
labels to the icon-only buttons: for the password visibility toggle (the button
that calls setIsPasswordVisible and renders EyeIcon/EyeOffIcon) add an
appropriate aria-label that reflects the action/state (e.g., "Show password"
when isPasswordVisible is false and "Hide password" when true); for the clear
button (the button that calls onClear and renders XCircleIcon) add an aria-label
such as "Clear search" or "Clear input". Ensure the labels update to match state
where applicable and leave the existing click handlers (setIsPasswordVisible,
onClear) and icons unchanged.

71-89: getTextareaClasses still omits commonStyles.disabled.

commonStyles.disabled is included in both getInputClasses (line 58) and getSelectClasses (line 97), but remains absent here. Disabled textareas will not receive the grayed-out cursor-not-allowed styling.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 71 - 89, getTextareaClasses
currently omits commonStyles.disabled so disabled textareas don't get the
grayed-out/cursor-not-allowed styling; update getTextareaClasses (and its call
sites) to accept an isDisabled boolean (matching
getInputClasses/getSelectClasses) and include commonStyles.disabled in the
returned class list when isDisabled is true, preserving existing hasError and
isFullWidth behavior for consistency with the other helpers.

285-296: Select still triggers a React controlled/uncontrolled mixing warning.

defaultValue={placeholder ? "" : undefined} is placed before {...props}, so a consumer passing a value prop ends up with both value and defaultValue on the underlying <select>, which React flags as an illegal controlled/uncontrolled transition.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 285 - 296, The Select
component is causing a controlled/uncontrolled warning because defaultValue is
set before props are spread, so a consumer-supplied value prop can be passed
alongside defaultValue; update Select so defaultValue is only applied when the
consumer did not supply a value—inspect the forwarded props in the Select
function (the {...props} object) and conditionally set defaultValue based on
whether props.value is undefined (or move defaultValue after spreading props and
only add it when no value exists), referencing the Select component and the
defaultValue / {...props} usage to locate the change.

141-143: hasRightContent still unconditionally includes the password toggle when disabled.

type === "password" is not guarded by !disabled, so right padding is applied even though the toggle button is hidden (Line 179: type === "password" && !disabled).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 141 - 143, The computed
boolean hasRightContent incorrectly includes the password toggle even when the
input is disabled; update the expression that builds hasRightContent to only
consider the password toggle when type === "password" && !disabled (keep
existing checks for rightIcon and the search clear behavior using isSearch,
props.value and onClear unchanged), so padding only appears when the toggle is
actually rendered; adjust the hasRightContent declaration (and any related
usage) accordingly.

285-296: Select still triggers a React controlled/uncontrolled mixing warning.

defaultValue={placeholder ? "" : undefined} is set before {...props}, so a consumer who passes value ends up with both value and defaultValue on the underlying <select>, which React flags as a controlled/uncontrolled conflict.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 285 - 296, The Select
component sets defaultValue before spreading {...props}, causing defaultValue to
collide with a consumer-supplied value and trigger controlled/uncontrolled
warnings; update the Select render so that defaultValue is only applied when the
consumer has not provided a controlled value (i.e., props.value is undefined) or
move the defaultValue application after spreading props so a provided value will
override it; locate the React.forwardRef Select function and adjust the
defaultValue logic around the spread of {...props} (referencing Select, props,
defaultValue, and getSelectClasses) to ensure defaultValue is omitted when
props.value exists.

179-196: Password toggle and clear buttons still lack aria-label.

Both interactive buttons remain without accessible labels, leaving screen-reader users without context for what the buttons do.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 179 - 196, The
password-toggle and clear buttons in inputBox.tsx lack accessible labels; update
the button for toggling password visibility (where setIsPasswordVisible and
isPasswordVisible are used) to include an aria-label that reflects state (e.g.,
"Show password" when isPasswordVisible is false and "Hide password" when true),
and add an aria-label to the search clear button (where isSearch, props.value
and onClear are used) such as "Clear search input"; ensure these labels are
localized/consistent with other UI text if applicable.

71-89: getTextareaClasses still omits commonStyles.disabled.

commonStyles.disabled is included in both getInputClasses (line 58) and getSelectClasses (line 97), but is absent here. Disabled textareas will not receive grayed-out or cursor-not-allowed styling.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 71 - 89, getTextareaClasses
is missing inclusion of commonStyles.disabled so disabled textareas don't get
the grayed/cursor-not-allowed styling; update getTextareaClasses to include
commonStyles.disabled the same way getInputClasses and getSelectClasses do (add
commonStyles.disabled into the returned class array alongside
commonStyles.base/commonStyles.focus/stateClass/widthClass) and ensure it is
added conditionally via the same truthy filter pattern so existing behavior is
preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/shared/ui/inputBox/inputBox.tsx`:
- Around line 18-20: The CSS arbitrary-value fallback strings in inputBox.tsx
are using backticks and produce invalid CSS; update the error and defaultBorder
string values (the error and defaultBorder constants) to remove the backtick
characters from the var() fallback values (e.g., change var(--color-error-500,
`#EF4444`) to var(--color-error-500, `#EF4444`) and var(--color-gray-300,
`#CCCCCC`) to var(--color-gray-300, `#CCCCCC`)) so they match the valid style used
in commonStyles.base/disabled/focus.
- Around line 18-20: In the commonStyles object (in inputBox.tsx) remove the
literal backticks inside the CSS arbitrary-value fallbacks so the Tailwind var()
fallbacks are valid: update the error property string used in commonStyles (the
value containing border-[color:var(--color-error-500,`#EF4444`)]! and
focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!) to use
var(--color-error-500,`#EF4444`) and var(--color-error-100,`#FEE2E2`) without
backticks, and update defaultBorder
(border-[color:var(--color-gray-300,`#CCCCCC`)] ) to use
var(--color-gray-300,`#CCCCCC`) so the class names produce valid CSS/Tailwind
arbitrary values.

---

Duplicate comments:
In `@src/shared/ui/inputBox/inputBox.tsx`:
- Line 195: The XCircleIcon is rendered non-square because inputBox.tsx passes
width={16} and the component spreads {...props} after height={size}, so height
stays 20; update the usage in inputBox.tsx to pass size={16} (not width) when
rendering <XCircleIcon> so both width and height are set uniformly by the icon
component.
- Around line 141-143: The hasRightContent calculation adds padding for password
fields even when disabled; update the Boolean expression used to compute
hasRightContent (the const hasRightContent) to only include the password case
when the input is not disabled (i.e., include a !disabled guard alongside type
=== "password"); keep the existing checks for rightIcon, isSearch && props.value
&& onClear unchanged so the password toggle padding is only applied when the
password toggle button will actually render.
- Line 195: The XCircleIcon is being rendered non-square because width={16}
overrides only width while the component's props set height after, so change the
usage in inputBox.tsx from passing width={16} to using size={16} on the
XCircleIcon component to ensure both width and height are set to 16 (locate the
XCircleIcon JSX in the inputBox.tsx file).
- Around line 179-196: Add accessible labels to the icon-only buttons: for the
password visibility toggle (the button that calls setIsPasswordVisible and
renders EyeIcon/EyeOffIcon) add an appropriate aria-label that reflects the
action/state (e.g., "Show password" when isPasswordVisible is false and "Hide
password" when true); for the clear button (the button that calls onClear and
renders XCircleIcon) add an aria-label such as "Clear search" or "Clear input".
Ensure the labels update to match state where applicable and leave the existing
click handlers (setIsPasswordVisible, onClear) and icons unchanged.
- Around line 71-89: getTextareaClasses currently omits commonStyles.disabled so
disabled textareas don't get the grayed-out/cursor-not-allowed styling; update
getTextareaClasses (and its call sites) to accept an isDisabled boolean
(matching getInputClasses/getSelectClasses) and include commonStyles.disabled in
the returned class list when isDisabled is true, preserving existing hasError
and isFullWidth behavior for consistency with the other helpers.
- Around line 285-296: The Select component is causing a controlled/uncontrolled
warning because defaultValue is set before props are spread, so a
consumer-supplied value prop can be passed alongside defaultValue; update Select
so defaultValue is only applied when the consumer did not supply a value—inspect
the forwarded props in the Select function (the {...props} object) and
conditionally set defaultValue based on whether props.value is undefined (or
move defaultValue after spreading props and only add it when no value exists),
referencing the Select component and the defaultValue / {...props} usage to
locate the change.
- Around line 141-143: The computed boolean hasRightContent incorrectly includes
the password toggle even when the input is disabled; update the expression that
builds hasRightContent to only consider the password toggle when type ===
"password" && !disabled (keep existing checks for rightIcon and the search clear
behavior using isSearch, props.value and onClear unchanged), so padding only
appears when the toggle is actually rendered; adjust the hasRightContent
declaration (and any related usage) accordingly.
- Around line 285-296: The Select component sets defaultValue before spreading
{...props}, causing defaultValue to collide with a consumer-supplied value and
trigger controlled/uncontrolled warnings; update the Select render so that
defaultValue is only applied when the consumer has not provided a controlled
value (i.e., props.value is undefined) or move the defaultValue application
after spreading props so a provided value will override it; locate the
React.forwardRef Select function and adjust the defaultValue logic around the
spread of {...props} (referencing Select, props, defaultValue, and
getSelectClasses) to ensure defaultValue is omitted when props.value exists.
- Around line 179-196: The password-toggle and clear buttons in inputBox.tsx
lack accessible labels; update the button for toggling password visibility
(where setIsPasswordVisible and isPasswordVisible are used) to include an
aria-label that reflects state (e.g., "Show password" when isPasswordVisible is
false and "Hide password" when true), and add an aria-label to the search clear
button (where isSearch, props.value and onClear are used) such as "Clear search
input"; ensure these labels are localized/consistent with other UI text if
applicable.
- Around line 71-89: getTextareaClasses is missing inclusion of
commonStyles.disabled so disabled textareas don't get the
grayed/cursor-not-allowed styling; update getTextareaClasses to include
commonStyles.disabled the same way getInputClasses and getSelectClasses do (add
commonStyles.disabled into the returned class array alongside
commonStyles.base/commonStyles.focus/stateClass/widthClass) and ensure it is
added conditionally via the same truthy filter pattern so existing behavior is
preserved.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd8a233 and 46cad0a.

📒 Files selected for processing (1)
  • src/shared/ui/inputBox/inputBox.tsx

Comment on lines +18 to +20
error:
"border-[color:var(--color-error-500,`#EF4444`)]! focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!",
defaultBorder: "border-[color:var(--color-gray-300,`#CCCCCC`)]",
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.

⚠️ Potential issue | 🔴 Critical

Backtick characters in CSS arbitrary-value fallbacks produce invalid CSS.

Lines 19 and 20 embed backtick characters inside the var() fallback values:

"border-[color:var(--color-error-500,`#EF4444`)]!"
"border-[color:var(--color-gray-300,`#CCCCCC`)]"

Backtick (`) is not a valid CSS syntax character. Tailwind does minimal interpretation of arbitrary values — it simply injects the literal value into the generated rule. This means Tailwind will emit var(--color-error-500, #EF4444) verbatim into the stylesheet, which browsers will reject as an invalid value, causing the error border and the default border color to silently fail whenever the CSS custom property is not defined. Compare with the correctly written commonStyles.base, disabled, and focus constants on lines 13–17, which all use bare hex values without backticks.

Note: the previous review's proposed fix for the ! suffix also retained these backticks, so the issue was never resolved.

🐛 Proposed fix: remove backtick characters from fallback color values
  error:
-   "border-[color:var(--color-error-500,`#EF4444`)]! focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!",
-  defaultBorder: "border-[color:var(--color-gray-300,`#CCCCCC`)]",
+   "border-[color:var(--color-error-500,`#EF4444`)]! focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!",
+  defaultBorder: "border-[color:var(--color-gray-300,`#CCCCCC`)]",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 18 - 20, The CSS
arbitrary-value fallback strings in inputBox.tsx are using backticks and produce
invalid CSS; update the error and defaultBorder string values (the error and
defaultBorder constants) to remove the backtick characters from the var()
fallback values (e.g., change var(--color-error-500, `#EF4444`) to
var(--color-error-500, `#EF4444`) and var(--color-gray-300, `#CCCCCC`) to
var(--color-gray-300, `#CCCCCC`)) so they match the valid style used in
commonStyles.base/disabled/focus.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd "inputBox.tsx" --type f

Repository: ajou-industry-matching/aim-frontend

Length of output: 114


🏁 Script executed:

cat -n src/shared/ui/inputBox/inputBox.tsx | head -30

Repository: ajou-industry-matching/aim-frontend

Length of output: 1508


🌐 Web query:

Tailwind CSS v4 arbitrary values backtick syntax color fallback

💡 Result:

  • The backticks you’re seeing in Tailwind docs (for example text-[]) are documentation formatting to indicate a placeholder — you don’t type backticks in your class name. (tailwindcss.com)

  • Tailwind v4 arbitrary color value syntax is still:

  • If you want a CSS-variable fallback color, put it inside var() yourself using an arbitrary value:

    • Non-ambiguous utilities:
      • bg-[var(--brand,#0ea5e9)]
    • For text- (can be font-size or color), add Tailwind’s type hint:
  • The v4 shorthand form text-(--my-color) is only for var(--my-color); if you need a fallback, use the bracket form shown above. (tailwindcss.com)

Citations:


Remove backtick characters from CSS arbitrary-value fallbacks in commonStyles.

Lines 19–20 contain literal backticks inside the var() fallback values:

"border-[color:var(--color-error-500,`#EF4444`)]!"
"border-[color:var(--color-gray-300,`#CCCCCC`)]"

Backticks are not valid in CSS or Tailwind arbitrary values; they are generated as literal characters in the class name and break the color fallback syntax. The correct syntax is var(--color-error-500,#EF4444) without backticks.

Fix
  error:
-   "border-[color:var(--color-error-500,`#EF4444`)]! focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!",
-  defaultBorder: "border-[color:var(--color-gray-300,`#CCCCCC`)]",
+   "border-[color:var(--color-error-500,`#EF4444`)]! focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!",
+  defaultBorder: "border-[color:var(--color-gray-300,`#CCCCCC`)]",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/ui/inputBox/inputBox.tsx` around lines 18 - 20, In the
commonStyles object (in inputBox.tsx) remove the literal backticks inside the
CSS arbitrary-value fallbacks so the Tailwind var() fallbacks are valid: update
the error property string used in commonStyles (the value containing
border-[color:var(--color-error-500,`#EF4444`)]! and
focus:shadow-[0_0_0_3px_var(--color-error-100,`#FEE2E2`)]!) to use
var(--color-error-500,`#EF4444`) and var(--color-error-100,`#FEE2E2`) without
backticks, and update defaultBorder
(border-[color:var(--color-gray-300,`#CCCCCC`)] ) to use
var(--color-gray-300,`#CCCCCC`) so the class names produce valid CSS/Tailwind
arbitrary values.

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] 공통 InputBox 컴포넌트 구현

3 participants