Skip to content

Add DropdownButton and rename ButtonWithIcon into ButtonIcon#105

Open
Diubii wants to merge 9 commits intomainfrom
Diubii/button
Open

Add DropdownButton and rename ButtonWithIcon into ButtonIcon#105
Diubii wants to merge 9 commits intomainfrom
Diubii/button

Conversation

@Diubii
Copy link
Copy Markdown
Contributor

@Diubii Diubii commented May 3, 2026

Closes #12

@Diubii Diubii self-assigned this May 3, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

Walkthrough

A new DropdownButton component is added to support language selection, with interfaces defining its shape and props. The ButtonIcon component is renamed and its import path corrected. The Home page integrates the dropdown with Italian and English language options.

Changes

Language Selection Dropdown

Layer / File(s) Summary
Component Definitions
src/components/button-dropdown.tsx
New DropdownOption and ButtonDropdownProps interfaces define the dropdown shape. DropdownButton maps options to SelectItem elements and wires placeholder, value, and onChange props.
Component Renaming
src/components/button-icon.tsx
ButtonWithIcon is renamed to ButtonIcon and its Button import path is updated from ./button to ./ui/button.
Page Integration
src/app/page.tsx
DropdownButton is imported and rendered in the Home page with "Select language" placeholder and Italian (it) / English (en) options. Layout wrapper is updated to flex flex-col items-center gap-4 to center the dropdown.

Possibly related PRs

  • Button #34: Modifies button UI component imports and naming conventions, aligning with the ButtonIcon rename and ui/button import path changes in this PR.
🚥 Pre-merge checks | ✅ 2 | ❌ 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.
Linked Issues check ❓ Inconclusive Linked issue #12 provides no specific coding requirements or objectives, making it impossible to validate whether changes meet stated requirements. Review issue #12 to confirm it specifies the DropdownButton and ButtonIcon rename requirements, or update the PR description with explicit objectives.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes both main changes: adding a DropdownButton component and renaming ButtonWithIcon to ButtonIcon, matching the changeset.
Out of Scope Changes check ✅ Passed All changes (DropdownButton addition, ButtonIcon rename, and import path update in button-icon.tsx) are directly related to the PR title and appear within scope.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

🧹 Nitpick comments (2)
src/components/button-icon.tsx (1)

4-22: ⚡ Quick win

No HTML button props are forwarded — the component cannot respond to interactions.

The current signature only accepts variant, icon, text, and iconPosition. There is no way for callers to pass onClick, disabled, type, className, or any aria-* / data-* attribute. In practice this makes ButtonIcon non-interactive and inaccessible as a standalone component.

♻️ Proposed fix: forward rest props to Button
-export function ButtonIcon({
+export function ButtonIcon({
   variant = "primary",
   icon: Icon,
   text,
   iconPosition = "left",
+  ...props
 }: {
   variant?: "primary" | "tertiary" | "tertiaryBlur"
   icon: IconType
   text: string
   iconPosition?: "left" | "right"
-}) {
+} & React.ComponentProps<"button">) {
   return (
-    <Button variant={variant} size="lg">
+    <Button variant={variant} size="lg" {...props}>
       {iconPosition === "left" && <Icon />}
       {text}
       {iconPosition === "right" && <Icon />}
     </Button>
   )
 }

Also add import type * as React from "react" (or import React from "react") at the top.

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

In `@src/components/button-icon.tsx` around lines 4 - 22, ButtonIcon currently
only accepts variant, icon, text and iconPosition so callers cannot pass
interactions or attributes; update ButtonIcon to accept and forward arbitrary
button props by extending the appropriate button props type (e.g.,
React.ButtonHTMLAttributes<HTMLButtonElement> or the Button component's prop
type) and collect the rest with a rest pattern (e.g., ...rest) and pass them
into the rendered <Button> (the Button component) so onClick, disabled, type,
className, aria-* and data-* work; also add the React type import (import type *
as React from "react" or equivalent) so the prop type references compile.
src/components/button-dropdown.tsx (1)

14-14: 💤 Low value

Consider deriving the size type from SelectTrigger to stay DRY.

The "default" | "sm" union is already defined as a custom prop on SelectTrigger. If that definition ever changes, ButtonDropdownProps silently diverges.

♻️ Proposed refactor
+import type React from "react"
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
-  size?: "default" | "sm"
+  size?: React.ComponentProps<typeof SelectTrigger>["size"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/button-dropdown.tsx` at line 14, The ButtonDropdownProps
currently repeats the size union ("default" | "sm") and should derive it from
SelectTrigger to avoid divergence; update the size definition in
ButtonDropdownProps to reference the existing prop type on SelectTrigger (e.g.,
use React.ComponentProps<typeof SelectTrigger>['size'] or the appropriate
exported prop type) so ButtonDropdownProps.size is always driven by
SelectTrigger's type; adjust imports if necessary to access SelectTrigger in
src/components/button-dropdown.tsx.
🤖 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/app/page.tsx`:
- Around line 18-24: The DropdownButton in page.tsx is missing value and
onChange wiring so selections never update app state; add a controlled state or
hook to handle language changes: inside the page component (or a client wrapper)
create state (e.g., useState or an i18n/context hook) to hold the selected
language, pass that state as value and an onChange handler to DropdownButton,
and invoke your language-switch logic (or routing/i18n API) from the handler; if
you intentionally defer implementing the handler, add a clear TODO noting that
DropdownButton needs a value/onChange wired to the app's language switcher.

---

Nitpick comments:
In `@src/components/button-dropdown.tsx`:
- Line 14: The ButtonDropdownProps currently repeats the size union ("default" |
"sm") and should derive it from SelectTrigger to avoid divergence; update the
size definition in ButtonDropdownProps to reference the existing prop type on
SelectTrigger (e.g., use React.ComponentProps<typeof SelectTrigger>['size'] or
the appropriate exported prop type) so ButtonDropdownProps.size is always driven
by SelectTrigger's type; adjust imports if necessary to access SelectTrigger in
src/components/button-dropdown.tsx.

In `@src/components/button-icon.tsx`:
- Around line 4-22: ButtonIcon currently only accepts variant, icon, text and
iconPosition so callers cannot pass interactions or attributes; update
ButtonIcon to accept and forward arbitrary button props by extending the
appropriate button props type (e.g.,
React.ButtonHTMLAttributes<HTMLButtonElement> or the Button component's prop
type) and collect the rest with a rest pattern (e.g., ...rest) and pass them
into the rendered <Button> (the Button component) so onClick, disabled, type,
className, aria-* and data-* work; also add the React type import (import type *
as React from "react" or equivalent) so the prop type references compile.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d49a7bea-e2a9-4eed-aab2-2fbc3ca3aa88

📥 Commits

Reviewing files that changed from the base of the PR and between 3665328 and 6fc778d.

📒 Files selected for processing (3)
  • src/app/page.tsx
  • src/components/button-dropdown.tsx
  • src/components/button-icon.tsx

Comment thread src/app/page.tsx
Comment on lines +18 to +24
<DropdownButton
placeholder="Select language"
options={[
{ label: "Italian", value: "it" },
{ label: "English", value: "en" },
]}
/>
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 | ⚡ Quick win

DropdownButton has no onChange/value — language selection is a no-op.

Without onChange and managed value, user selections are swallowed by Radix internals and never reach application state. If the language-switching logic is deferred, add a // TODO comment; otherwise wire up useState (or a context/i18n hook) to make the selection functional.

⚡ Minimal wiring example (client component)
+"use client"
+import { useState } from "react"
 import { DropdownButton } from "@/components/button-dropdown"

 export default function Home() {
+  const [lang, setLang] = useState<string>()
   return (
     <main className="w-full">
       ...
       <DropdownButton
         placeholder="Select language"
         options={[
           { label: "Italian", value: "it" },
           { label: "English", value: "en" },
         ]}
+        value={lang}
+        onChange={setLang}
       />

Note: actual i18n integration (e.g. next-intl, next/navigation locale routing) would replace the useState placeholder above.

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

In `@src/app/page.tsx` around lines 18 - 24, The DropdownButton in page.tsx is
missing value and onChange wiring so selections never update app state; add a
controlled state or hook to handle language changes: inside the page component
(or a client wrapper) create state (e.g., useState or an i18n/context hook) to
hold the selected language, pass that state as value and an onChange handler to
DropdownButton, and invoke your language-switch logic (or routing/i18n API) from
the handler; if you intentionally defer implementing the handler, add a clear
TODO noting that DropdownButton needs a value/onChange wired to the app's
language switcher.

@Diubii Diubii mentioned this pull request May 3, 2026
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.

Button

1 participant