[Feat] #69 - 공통 Avatars 컴포넌트 추가#73
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 9 minutes and 21 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds Avatar and AvatarGroup components (sizes, status, badge, fallbacks and grouped overflow), ListItem and Table components (selection, checkboxes, empty state), Storybook stories for avatars/lists/tables, and several new SVG icon exports. Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
src/shared/ui/avatars/avatars.tsx (3)
88-90: Consider handling empty string edge case.While
nameis guarded by a truthy check beforegetInitialis called, the function itself doesn't handle whitespace-only strings (e.g.," ".charAt(0)returns" "). Consider trimming or validating input.🔧 Optional defensive improvement
const getInitial = (name: string): string => { - return name.charAt(0).toUpperCase(); + const trimmed = name.trim(); + return trimmed.charAt(0).toUpperCase(); };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/avatars/avatars.tsx` around lines 88 - 90, getInitial currently uses name.charAt(0) and doesn't handle whitespace-only or empty strings; update the getInitial function to trim the input (use name.trim()), check if the trimmed string has length > 0, and then return the first character uppercased, otherwise return a safe fallback (e.g., an empty string or a placeholder like '?') so callers won't receive a whitespace character for whitespace-only names.
191-197: Overflow indicator font size doesn't scale with avatar size.The
+Nindicator uses a fixedtext-[14px]regardless of thesizeprop. For consistency with the avatar text sizing, consider usingavatarTextSizeClasses[size]or a scaled-down variant.✨ Optional: Scale overflow text with size
{hiddenCount > 0 && ( <div - className={`${avatarSizeClasses[size]} relative inline-flex items-center justify-center rounded-full bg-[color:var(--color-gray-200,`#E5E5E5`)] text-[color:var(--color-gray-600,`#666666`)] font-bold text-[14px] border-[3px] border-white box-content shadow-[0_2px_8px_rgba(0,0,0,0.08)] flex-shrink-0 z-0`} + className={`${avatarSizeClasses[size]} ${avatarTextSizeClasses[size]} relative inline-flex items-center justify-center rounded-full bg-[color:var(--color-gray-200,`#E5E5E5`)] text-[color:var(--color-gray-600,`#666666`)] font-bold border-[3px] border-white box-content shadow-[0_2px_8px_rgba(0,0,0,0.08)] flex-shrink-0 z-0`} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/avatars/avatars.tsx` around lines 191 - 197, The overflow indicator currently uses a fixed text size (text-[14px]) so +{hiddenCount} doesn't scale with the avatar; update the overflow div inside the Avatars component to use the existing avatarTextSizeClasses mapping keyed by size (or a scaled-down variant of avatarTextSizeClasses[size]) instead of text-[14px], ensuring the class list combines avatarSizeClasses[size], avatarTextSizeClasses[size] (or its scaled-down alternative), and the existing layout classes so the +N text scales consistently with other avatar text.
136-141: Handle image load errors gracefully.If the image URL fails to load (404, network error, etc.), the browser displays a broken image icon instead of falling back to initials or the default icon. Consider using
useStateto track load errors and render the fallback.🖼️ Proposed approach for image error handling
+import React, { useState } from "react"; + export const Avatar = ({ src, name, // ... other props }: AvatarProps): React.ReactElement => { + const [imgError, setImgError] = useState(false); const isClickable = !!onClick; // ... return ( <div className={avatarClasses} onClick={onClick}> - {src ? ( + {src && !imgError ? ( <img src={src} alt={name || "User avatar"} className="w-full h-full object-cover rounded-full" + onError={() => setImgError(true)} /> ) : name ? ( // ... initials rendering ) : ( // ... default icon )}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/avatars/avatars.tsx` around lines 136 - 141, The img element rendering branch that uses {src ? ( <img src={src} alt={name || "User avatar"} ... /> )} needs graceful error handling: add a useState flag (e.g., hasImageError) in the Avatar component (src/shared/ui/avatars/avatars.tsx), attach an onError handler to the <img> that sets the flag true, and change the conditional to render the existing fallback (initials or default icon) when hasImageError is true or when src is falsy; ensure you also clear the flag on successful load if you add an onLoad handler so re-tries work.
🤖 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/avatars/avatars.tsx`:
- Around line 133-134: The clickable avatar div using avatarClasses and onClick
needs keyboard and screen-reader accessibility: when onClick is provided, add
role="button", tabIndex={0} and an onKeyDown handler that calls the same onClick
for Enter/Space keys, and ensure an appropriate aria-label or pass-through aria
props if available; only attach these attributes/handler when onClick exists so
non-interactive avatars remain semantic. Ensure the onKeyDown logic maps Space
and Enter to preventDefault as needed and invokes the same callback so keyboard
users can activate the avatar.
In `@src/shared/ui/lists/lists.stories.tsx`:
- Line 157: The current isAllChecked calculation uses data.filter((r) =>
!r.isDisabled).every((r) => r.isSelected) which returns true for an empty array;
change it so it first computes the selectable rows (e.g., selectable =
data.filter(r => !r.isDisabled)) and then set isAllChecked to selectable.length
> 0 && selectable.every(r => r.isSelected) so the header checkbox is not checked
when there are zero selectable rows.
In `@src/shared/ui/lists/lists.tsx`:
- Around line 182-183: The clickable container currently rendered as a div
should be made keyboard-accessible: replace or modify the element that uses
getListItemClasses(isActive, isDisabled) and onClick={handleItemClick} so it
supports keyboard activation—either render a semantic <button> (preferred) or
add role="button", tabIndex={0}, and an onKeyDown handler that calls
handleItemClick on Enter/Space; also ensure isDisabled prevents activation (use
disabled prop for a button or aria-disabled when using a div/role) and update
classes via getListItemClasses accordingly so both Line 182 and the similar
container at Line 322–326 use the same accessible behavior.
- Around line 189-195: The checkbox input lacks an accessible name; update the
checkbox in src/shared/ui/lists/lists.tsx to provide an accessible label by
either wrapping the <input> with a <label> that contains visible text or by
adding an explicit aria-label or aria-labelledby attribute that describes the
checkbox purpose (use the same approach for the other checkbox instances using
isChecked/isDisabled). Ensure the label text is meaningful (e.g., "Select item",
or use the item title from props/state) and that aria-labelledby references an
existing element ID if you choose that route so screen readers can announce the
checkbox state correctly.
---
Nitpick comments:
In `@src/shared/ui/avatars/avatars.tsx`:
- Around line 88-90: getInitial currently uses name.charAt(0) and doesn't handle
whitespace-only or empty strings; update the getInitial function to trim the
input (use name.trim()), check if the trimmed string has length > 0, and then
return the first character uppercased, otherwise return a safe fallback (e.g.,
an empty string or a placeholder like '?') so callers won't receive a whitespace
character for whitespace-only names.
- Around line 191-197: The overflow indicator currently uses a fixed text size
(text-[14px]) so +{hiddenCount} doesn't scale with the avatar; update the
overflow div inside the Avatars component to use the existing
avatarTextSizeClasses mapping keyed by size (or a scaled-down variant of
avatarTextSizeClasses[size]) instead of text-[14px], ensuring the class list
combines avatarSizeClasses[size], avatarTextSizeClasses[size] (or its
scaled-down alternative), and the existing layout classes so the +N text scales
consistently with other avatar text.
- Around line 136-141: The img element rendering branch that uses {src ? ( <img
src={src} alt={name || "User avatar"} ... /> )} needs graceful error handling:
add a useState flag (e.g., hasImageError) in the Avatar component
(src/shared/ui/avatars/avatars.tsx), attach an onError handler to the <img> that
sets the flag true, and change the conditional to render the existing fallback
(initials or default icon) when hasImageError is true or when src is falsy;
ensure you also clear the flag on successful load if you add an onLoad handler
so re-tries work.
🪄 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
Run ID: a05c6ee3-aa9c-4605-9968-a8331bf3a97e
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
src/shared/ui/avatars/avatars.stories.tsxsrc/shared/ui/avatars/avatars.tsxsrc/shared/ui/lists/lists.stories.tsxsrc/shared/ui/lists/lists.tsx
| return ( | ||
| <div className={avatarClasses} onClick={onClick}> |
There was a problem hiding this comment.
Add accessibility attributes for clickable avatars.
When onClick is provided, the <div> becomes interactive but lacks keyboard accessibility. Screen reader users and keyboard-only users cannot interact with it.
♿ Proposed fix for accessibility
<div
className={avatarClasses}
onClick={onClick}
+ role={isClickable ? "button" : undefined}
+ tabIndex={isClickable ? 0 : undefined}
+ onKeyDown={isClickable ? (e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ onClick?.();
+ }
+ } : undefined}
+ aria-label={isClickable ? (name || "User avatar") : undefined}
>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/shared/ui/avatars/avatars.tsx` around lines 133 - 134, The clickable
avatar div using avatarClasses and onClick needs keyboard and screen-reader
accessibility: when onClick is provided, add role="button", tabIndex={0} and an
onKeyDown handler that calls the same onClick for Enter/Space keys, and ensure
an appropriate aria-label or pass-through aria props if available; only attach
these attributes/handler when onClick exists so non-interactive avatars remain
semantic. Ensure the onKeyDown logic maps Space and Enter to preventDefault as
needed and invokes the same callback so keyboard users can activate the avatar.
| <div className={getListItemClasses(isActive, isDisabled)} onClick={handleItemClick}> | ||
| {/* 체크박스 */} |
There was a problem hiding this comment.
Keyboard 접근 가능한 인터랙션으로 바꿔주세요
Line 182와 Line 325의 클릭 가능한 컨테이너가 div라서 키보드(Enter/Space)로 동작하지 않습니다. 접근성 관점에서 실제 사용이 막힐 수 있습니다.
♿ Proposed fix
+import React from "react";
+
+const isActivationKey = (key: string): boolean => key === "Enter" || key === " ";
...
export const ListItem = ({
...
}: ListItemProps): React.ReactElement => {
const handleItemClick = () => {
if (!isDisabled && onClick) onClick(id);
};
+
+ const handleItemKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
+ if (isDisabled || !onClick) return;
+ if (isActivationKey(e.key)) {
+ e.preventDefault();
+ onClick(id);
+ }
+ };
...
- return (
- <div className={getListItemClasses(isActive, isDisabled)} onClick={handleItemClick}>
+ return (
+ <div
+ className={getListItemClasses(isActive, isDisabled)}
+ onClick={handleItemClick}
+ role="button"
+ tabIndex={isDisabled ? -1 : 0}
+ aria-disabled={isDisabled}
+ onKeyDown={handleItemKeyDown}
+ >
...
{data.map((row) => {
...
const handleRowClick = () => {
if (!isDisabled && onRowClick) onRowClick(row.id);
};
+
+ const handleRowKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
+ if (isDisabled || !onRowClick) return;
+ if (isActivationKey(e.key)) {
+ e.preventDefault();
+ onRowClick(row.id);
+ }
+ };
...
<div
key={row.id}
className={getTableRowClasses(isSelected, isDisabled)}
onClick={handleRowClick}
+ role="button"
+ tabIndex={isDisabled ? -1 : 0}
+ aria-disabled={isDisabled}
+ onKeyDown={handleRowKeyDown}
>Also applies to: 322-326
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/shared/ui/lists/lists.tsx` around lines 182 - 183, The clickable
container currently rendered as a div should be made keyboard-accessible:
replace or modify the element that uses getListItemClasses(isActive, isDisabled)
and onClick={handleItemClick} so it supports keyboard activation—either render a
semantic <button> (preferred) or add role="button", tabIndex={0}, and an
onKeyDown handler that calls handleItemClick on Enter/Space; also ensure
isDisabled prevents activation (use disabled prop for a button or aria-disabled
when using a div/role) and update classes via getListItemClasses accordingly so
both Line 182 and the similar container at Line 322–326 use the same accessible
behavior.
| <input | ||
| type="checkbox" | ||
| checked={isChecked} | ||
| readOnly | ||
| disabled={isDisabled} | ||
| className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,#004A9C)]" | ||
| /> |
There was a problem hiding this comment.
체크박스에 접근 가능한 라벨이 필요합니다
Line 189, Line 275, Line 332의 체크박스에 접근 가능한 이름이 없어 스크린리더 사용성이 떨어집니다.
🏷️ Proposed fix
<input
type="checkbox"
checked={isChecked}
readOnly
disabled={isDisabled}
+ aria-label={`${title} 선택`}
className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,`#004A9C`)]"
/>
...
<input
type="checkbox"
checked={isAllChecked}
onChange={(e) => onCheckAll && onCheckAll(e.target.checked)}
+ aria-label="모든 행 선택"
className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,`#004A9C`)]"
/>
...
<input
type="checkbox"
checked={isSelected}
readOnly
disabled={isDisabled}
+ aria-label={`${row.id} 행 선택`}
className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,`#004A9C`)]"
/>Also applies to: 275-280, 332-338
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/shared/ui/lists/lists.tsx` around lines 189 - 195, The checkbox input
lacks an accessible name; update the checkbox in src/shared/ui/lists/lists.tsx
to provide an accessible label by either wrapping the <input> with a <label>
that contains visible text or by adding an explicit aria-label or
aria-labelledby attribute that describes the checkbox purpose (use the same
approach for the other checkbox instances using isChecked/isDisabled). Ensure
the label text is meaningful (e.g., "Select item", or use the item title from
props/state) and that aria-labelledby references an existing element ID if you
choose that route so screen readers can announce the checkbox state correctly.
isAllChecked 계산식의 빈 배열 케이스를 보정 Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
src/shared/ui/avatars/avatars.tsx (1)
124-124:⚠️ Potential issue | 🟠 MajorMake clickable avatars keyboard-accessible.
Line 124 uses a clickable
divwithout keyboard semantics, so keyboard users cannot activate it.♿ Proposed fix
export const Avatar = ({ @@ }: AvatarProps): React.ReactElement => { const isClickable = !!onClick; + const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => { + if (!isClickable) return; + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + onClick?.(); + } + }; @@ - return ( - <div className={avatarClasses} onClick={onClick}> + return ( + <div + className={avatarClasses} + onClick={onClick} + role={isClickable ? "button" : undefined} + tabIndex={isClickable ? 0 : undefined} + onKeyDown={isClickable ? handleKeyDown : undefined} + aria-label={isClickable ? (name ? `${name} avatar` : "User avatar") : undefined} + >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/avatars/avatars.tsx` at line 124, The clickable avatar uses a raw div with avatarClasses and onClick, which is not keyboard-accessible; update the avatar root element to expose button semantics by adding role="button", tabIndex={0}, and an onKeyDown handler that calls the same onClick callback when Enter or Space is pressed (and ensure it prevents default for Space). Keep the existing onClick behavior and only add these attributes/handler where avatarClasses and onClick are used so keyboard users can activate the avatar.src/shared/ui/lists/lists.tsx (2)
145-145:⚠️ Potential issue | 🟠 MajorInteractive rows still need keyboard activation support.
Line 145 and Line 285-Line 289 use clickable
divcontainers without keyboard semantics (Enter/Space), which blocks keyboard-only usage.♿ Proposed fix
+const isActivationKey = (key: string): boolean => key === "Enter" || key === " "; export const ListItem = ({ @@ }: ListItemProps): React.ReactElement => { @@ + const handleItemKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => { + if (isDisabled || !onClick) return; + if (isActivationKey(e.key)) { + e.preventDefault(); + onClick(id); + } + }; return ( - <div className={getListItemClasses(isActive, isDisabled)} onClick={handleItemClick}> + <div + className={getListItemClasses(isActive, isDisabled)} + onClick={handleItemClick} + role="button" + tabIndex={isDisabled ? -1 : 0} + aria-disabled={isDisabled} + onKeyDown={handleItemKeyDown} + > @@ const handleRowClick = () => { if (!isDisabled && onRowClick) onRowClick(row.id); }; + const handleRowKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => { + if (isDisabled || !onRowClick) return; + if (isActivationKey(e.key)) { + e.preventDefault(); + onRowClick(row.id); + } + }; return ( <div key={row.id} className={getTableRowClasses(isSelected, isDisabled)} onClick={handleRowClick} + role="button" + tabIndex={isDisabled ? -1 : 0} + aria-disabled={isDisabled} + onKeyDown={handleRowKeyDown} >Also applies to: 285-289
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/lists/lists.tsx` at line 145, The interactive list rows using the getListItemClasses(...) container and handleItemClick currently only handle mouse clicks; add keyboard accessibility by making the container focusable and semantic: add role="button", tabIndex={isDisabled ? -1 : 0}, and aria-disabled={isDisabled}, then implement an onKeyDown handler that calls handleItemClick when Enter is pressed or when Space is pressed (prevent default for Space to avoid page scroll); ensure the handler respects isDisabled the same way as the onClick path so disabled rows remain inert.
152-158:⚠️ Potential issue | 🟠 MajorAdd accessible names to all checkboxes.
The checkboxes at Line 152-Line 158, Line 238-Line 243, and Line 295-Line 301 do not expose meaningful labels to screen readers.
🏷️ Proposed fix
<input type="checkbox" checked={isChecked} readOnly disabled={isDisabled} + aria-label={`${title} 선택`} className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,`#004A9C`)]" /> @@ <input type="checkbox" checked={isAllChecked} onChange={(e) => onCheckAll && onCheckAll(e.target.checked)} + aria-label="모든 행 선택" className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,`#004A9C`)]" /> @@ <input type="checkbox" checked={isSelected} readOnly disabled={isDisabled} + aria-label={`${row.id} 행 선택`} className="w-4 h-4 cursor-pointer accent-[color:var(--color-primary-800,`#004A9C`)]" />Also applies to: 238-243, 295-301
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/lists/lists.tsx` around lines 152 - 158, The checkbox inputs in src/shared/ui/lists/lists.tsx (the input elements using props isChecked and isDisabled and the className "w-4 h-4 cursor-pointer…") lack accessible names; update each checkbox (the ones referencing isChecked/isDisabled at the three occurrences) to expose a meaningful label by either adding an aria-label or aria-labelledby that describes the checkbox purpose (or by associating it with a visible <label> via id/htmlFor), ensuring the label text is specific to the checkbox context; keep existing props (checked, readOnly, disabled, className) and add the aria attribute or id/htmlFor pair to each input so screen readers can announce the control.
🤖 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/avatars/avatars.tsx`:
- Around line 164-166: The calculations for visibleAvatars and hiddenCount can
produce incorrect results when maxVisible is 0 or negative; clamp maxVisible to
a valid range before using it (e.g., compute a safeMax = Math.max(0,
Math.min(maxVisible, avatars.length))) and then use safeMax in
avatars.slice(...) and in the hiddenCount computation so visibleAvatars and
hiddenCount are never derived from a negative or out-of-range maxVisible.
---
Duplicate comments:
In `@src/shared/ui/avatars/avatars.tsx`:
- Line 124: The clickable avatar uses a raw div with avatarClasses and onClick,
which is not keyboard-accessible; update the avatar root element to expose
button semantics by adding role="button", tabIndex={0}, and an onKeyDown handler
that calls the same onClick callback when Enter or Space is pressed (and ensure
it prevents default for Space). Keep the existing onClick behavior and only add
these attributes/handler where avatarClasses and onClick are used so keyboard
users can activate the avatar.
In `@src/shared/ui/lists/lists.tsx`:
- Line 145: The interactive list rows using the getListItemClasses(...)
container and handleItemClick currently only handle mouse clicks; add keyboard
accessibility by making the container focusable and semantic: add role="button",
tabIndex={isDisabled ? -1 : 0}, and aria-disabled={isDisabled}, then implement
an onKeyDown handler that calls handleItemClick when Enter is pressed or when
Space is pressed (prevent default for Space to avoid page scroll); ensure the
handler respects isDisabled the same way as the onClick path so disabled rows
remain inert.
- Around line 152-158: The checkbox inputs in src/shared/ui/lists/lists.tsx (the
input elements using props isChecked and isDisabled and the className "w-4 h-4
cursor-pointer…") lack accessible names; update each checkbox (the ones
referencing isChecked/isDisabled at the three occurrences) to expose a
meaningful label by either adding an aria-label or aria-labelledby that
describes the checkbox purpose (or by associating it with a visible <label> via
id/htmlFor), ensuring the label text is specific to the checkbox context; keep
existing props (checked, readOnly, disabled, className) and add the aria
attribute or id/htmlFor pair to each input so screen readers can announce the
control.
🪄 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
Run ID: 16b377f8-4709-42cc-8f46-99027a7e5ea1
📒 Files selected for processing (4)
src/shared/ui/avatars/avatars.tsxsrc/shared/ui/icons/index.tsxsrc/shared/ui/lists/lists.stories.tsxsrc/shared/ui/lists/lists.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/shared/ui/avatars/avatars.tsx (1)
183-188: Consider scaling the "+N" badge text size with the avatar size.The
text-[14px]is fixed regardless of thesizeprop. For larger avatars (e.g.,2xl,3xl), the badge text may appear disproportionately small; forxs, it may overflow.♻️ Suggested approach
Reuse
avatarTextSizeClasses[size]or create a dedicated map for badge text sizes:<div - className={`${avatarSizeClasses[size]} relative inline-flex items-center justify-center rounded-full bg-[color:var(--color-gray-200,`#E5E5E5`)] text-[color:var(--color-gray-600,`#666666`)] font-bold text-[14px] border-[3px] border-white box-content shadow-[0_2px_8px_rgba(0,0,0,0.08)] flex-shrink-0 z-0`} + className={`${avatarSizeClasses[size]} ${avatarTextSizeClasses[size]} relative inline-flex items-center justify-center rounded-full bg-[color:var(--color-gray-200,`#E5E5E5`)] text-[color:var(--color-gray-600,`#666666`)] font-bold border-[3px] border-white box-content shadow-[0_2px_8px_rgba(0,0,0,0.08)] flex-shrink-0 z-0`} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/ui/avatars/avatars.tsx` around lines 183 - 188, The "+N" badge currently uses a fixed class text-[14px] which doesn't scale with the avatar size; update the badge's class composition inside the Avatars component (the div rendering +{hiddenCount}) to use the existing avatarTextSizeClasses[size] (or add a badgeTextSizeClasses[size] map) instead of the hard-coded text-[14px], ensuring you include the computed size class alongside the other classes so the badge font scales correctly for sizes like xs, 2xl, 3xl.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/shared/ui/avatars/avatars.tsx`:
- Around line 183-188: The "+N" badge currently uses a fixed class text-[14px]
which doesn't scale with the avatar size; update the badge's class composition
inside the Avatars component (the div rendering +{hiddenCount}) to use the
existing avatarTextSizeClasses[size] (or add a badgeTextSizeClasses[size] map)
instead of the hard-coded text-[14px], ensuring you include the computed size
class alongside the other classes so the badge font scales correctly for sizes
like xs, 2xl, 3xl.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8e62b408-8b19-43d9-a419-fe649fbddb30
📒 Files selected for processing (1)
src/shared/ui/avatars/avatars.tsx
🔎 What is this PR?
📝 Changes
📸 Screenshots (선택)
📚 Background / Context (선택)
✔ Checklist
pnpm build)pnpm lint)🙏 Request
Summary by CodeRabbit
New Features
Documentation