Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(input-component): support icons left/right #5407

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

IndyVC
Copy link

@IndyVC IndyVC commented Oct 16, 2024

Using Icons inside an input field is something very common. Unfortunately, shadcn didn't truly provide it out of the box, while it easily could. This PR could solve it.

Following these issues:

I've also extended docs:
image

And code example:

import { MapIcon, MapPin } from "lucide-react"

import { Input } from "@/components/ui/input"

export function InputWithIcons() {
  return (
    <div>
      <Input>
        <Input.Icon side="left">
          <MapIcon />
        </Input.Icon>
        <Input.Icon side="right">
          <MapPin />
        </Input.Icon>
      </Input>
    </div>
  )
}

Copy link

vercel bot commented Oct 16, 2024

@IndyVC is attempting to deploy a commit to the shadcn-pro Team on Vercel.

A member of the Team first needs to authorize it.

@daanboschmans
Copy link

Can we have this merged? pls

@IndyVC
Copy link
Author

IndyVC commented Oct 21, 2024

@shadcn tagging you since I have no idea how this can get ever into shadcn with +- 700 prs 😅

({ children, className, ...props }, ref) => {
const Icons = useComposition(children, InputIcon.displayName)

if (Icons.length > 0) {

Choose a reason for hiding this comment

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

I’ve noticed one issue with composition. For my use case and most of the time when building other input components I’ve been playing with the padding-x property only on the side where the icon is added. This way, there’s no extra space on both sides from only one icon being present.

Something like this is what I thought could do the job:

 ...
 const Icons = useComposition(children, InputIcon.displayName);

    if (Icons.length > 0) {
      // Since we're sure that the children are InputIcon components, we can cast them to the correct type
      // to access the `side` prop
      type IconElement = React.ReactElement<InputIconProps>;

      const hasRightIcon = Icons.some(
        (icon) => (icon as IconElement).props.side === 'right',
      );
      const hasLeftIcon = Icons.some(
        (icon) =>
          (icon as IconElement).props.side === 'left' ||
          (icon as IconElement).props.side === undefined,
      );
      
      // conditionally check for composition (maybe add more variants such as left, right, true, false)
   ...

Copy link
Author

Choose a reason for hiding this comment

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

@florinkrasniqi I don't fully understand the comment:
do you mean I should be using px-3 instead of left-3 for example? (see iconVariants)

Choose a reason for hiding this comment

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

Sorry for any confusion. The whole idea is to not have input padding on both sides if only one icon is present but instead only on the icon side.

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.

3 participants