Skip to content

feat: limit badges to 2 with hover/click popover in UserListTable#8

Open
tomerqodo wants to merge 2 commits intocoderabbit_full_base_feat_limit_badges_to_2_with_hover_click_popover_in_userlisttable_pr8from
coderabbit_full_head_feat_limit_badges_to_2_with_hover_click_popover_in_userlisttable_pr8
Open

feat: limit badges to 2 with hover/click popover in UserListTable#8
tomerqodo wants to merge 2 commits intocoderabbit_full_base_feat_limit_badges_to_2_with_hover_click_popover_in_userlisttable_pr8from
coderabbit_full_head_feat_limit_badges_to_2_with_hover_click_popover_in_userlisttable_pr8

Conversation

@tomerqodo
Copy link

@tomerqodo tomerqodo commented Jan 29, 2026

Benchmark PR from agentic-review-benchmarks#8

Summary by CodeRabbit

  • New Features

    • Added a collapsible badge component that displays a limited number of badges with a "+N" overflow indicator for hidden items.
  • UI/UX Improvements

    • Enhanced badge rendering in insights and user management with responsive interactions (hover popover on desktop, static display on mobile).

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new LimitedBadges component for rendering collapsible badge lists with hover-triggered popovers, then refactors multiple components to use it. Changes include type safety improvements in UserListTable and export restructuring.

Changes

Cohort / File(s) Summary
New LimitedBadges Component
apps/web/components/ui/LimitedBadges.tsx
Introduces a new React client component that displays badges with configurable visibility limits. Visible badges render directly; overflow items collapse behind a "+N" badge that reveals a popover on desktop hover or remains static on mobile via useMediaQuery.
Badge List Integration
apps/web/modules/insights/components/ResponseValueCell.tsx, apps/web/modules/insights/hooks/useInsightsColumns.tsx
Replaces multi-badge hover-card logic with LimitedBadges component. Removed rowId prop and simplified rendering by mapping values to badge items with labels and variants.
UserListTable Refactoring
apps/web/modules/users/components/UserTable/UserListTable.tsx
Significant type safety improvements across React Table integration (ColumnDef, CellContext, HeaderContext). Replaces multiple Badge rendering blocks with LimitedBadges. Refactors export structure and adds explicit type annotations to column generation, cell rendering, and faceted value handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A new LimitedBadges hops into view,
Collapsing extras with a "+N" so true,
Types grow stronger, exports refined,
Popovers dance on desktop, mobile's kind!
Tables now sparkle with clarity's light. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
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.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing a LimitedBadges component that limits badge display to 2 items with a popover for overflow, and applies this primarily to UserListTable.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch coderabbit_full_head_feat_limit_badges_to_2_with_hover_click_popover_in_userlisttable_pr8

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

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

🤖 Fix all issues with AI agents
In `@apps/web/components/ui/LimitedBadges.tsx`:
- Around line 68-98: Hidden items are non-interactive spans with unstable keys;
update the rendering inside LimitedBadges so hiddenItems are rendered the same
way as visibleItems (use <Badge> or a focusable element with the item's onClick
handler and same hover/focus styles) and replace key={item.label} with a stable
unique key (e.g., item.id if provided, otherwise combine label+index like
`${item.label}-${index}`) for both visibleItems and hiddenItems to avoid
collisions and preserve click/filter behavior.

Comment on lines +68 to +98
{visibleItems.map((item, index) => (
<Badge key={item.label} variant={item.variant || "gray"} onClick={item.onClick}>
{item.label}
</Badge>
))}
{hasHiddenItems && (
<Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger asChild>
<Button
color="minimal"
className="h-auto p-0 border-0 hover:border-0"
aria-label={`Show ${hiddenItems.length} more items`}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}>
<Badge variant="gray">+{hiddenItems.length}</Badge>
</Button>
</PopoverTrigger>
<PopoverContent
side="bottom"
align="start"
className="w-fit p-2"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}>
<div className="flex flex-col gap-1">
{hiddenItems.map((item, index) => (
<span
key={item.label}
className="text-default cursor-pointer text-sm hover:text-emphasis">
{item.label}
</span>
))}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "LimitedBadges.tsx" -type f

Repository: agentic-review-benchmarks/cal.com-combined-coderabbit

Length of output: 139


🏁 Script executed:

cat -n ./apps/web/components/ui/LimitedBadges.tsx

Repository: agentic-review-benchmarks/cal.com-combined-coderabbit

Length of output: 3766


🏁 Script executed:

rg "LimitedBadges" --type tsx --type ts -A 3 -B 1

Repository: agentic-review-benchmarks/cal.com-combined-coderabbit

Length of output: 124


🏁 Script executed:

rg "LimitedBadges" -A 3 -B 1 --max-count 20

Repository: agentic-review-benchmarks/cal.com-combined-coderabbit

Length of output: 3627


🏁 Script executed:

rg "LimitedBadges" -A 15 apps/web/modules/users/components/UserTable/UserListTable.tsx

Repository: agentic-review-benchmarks/cal.com-combined-coderabbit

Length of output: 1807


🏁 Script executed:

rg "LimitedBadges" -A 10 apps/web/modules/insights/components/ResponseValueCell.tsx

Repository: agentic-review-benchmarks/cal.com-combined-coderabbit

Length of output: 556


Hidden items should be interactive with stable keys to match visible items' behavior.

Hidden items are rendered as non-interactive <span> elements and ignore item.onClick callbacks—breaking filter actions like those in UserListTable.tsx. Additionally, key={item.label} creates collision risk for duplicate labels in both visible and hidden items.

💡 Proposed fix
-      {visibleItems.map((item, index) => (
-        <Badge key={item.label} variant={item.variant || "gray"} onClick={item.onClick}>
+      {visibleItems.map((item, index) => (
+        <Badge key={`${item.label}-${index}`} variant={item.variant || "gray"} onClick={item.onClick}>
           {item.label}
         </Badge>
       ))}
@@
-              {hiddenItems.map((item, index) => (
-                <span
-                  key={item.label}
-                  className="text-default cursor-pointer text-sm hover:text-emphasis">
-                  {item.label}
-                </span>
-              ))}
+              {hiddenItems.map((item, index) => (
+                <button
+                  key={`${item.label}-${index}`}
+                  type="button"
+                  className="text-default text-left text-sm hover:text-emphasis"
+                  onClick={() => {
+                    item.onClick?.();
+                    setIsOpen(false);
+                  }}>
+                  {item.label}
+                </button>
+              ))}
🤖 Prompt for AI Agents
In `@apps/web/components/ui/LimitedBadges.tsx` around lines 68 - 98, Hidden items
are non-interactive spans with unstable keys; update the rendering inside
LimitedBadges so hiddenItems are rendered the same way as visibleItems (use
<Badge> or a focusable element with the item's onClick handler and same
hover/focus styles) and replace key={item.label} with a stable unique key (e.g.,
item.id if provided, otherwise combine label+index like
`${item.label}-${index}`) for both visibleItems and hiddenItems to avoid
collisions and preserve click/filter behavior.

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.

1 participant