ui
ui copied to clipboard
Feature Request: Icon Support for Input Fields
As a user, I would like to have the ability to display icons within input fields to provide visual cues or additional functionality. Icons could be used for indicating input content (e.g., search icon in a search field) or enhancing user experience. This feature enhancement would greatly improve the versatility and usability of the input fields in our application.
Related to https://github.com/shadcn-ui/ui/discussions/1552
I wrapped the input inside a div and placed the icon as a sibling to the input, using position relative (to the parent div) and just fine tune the position. This is my workaround this.
<div className="flex items-center py-4">
<MagnifyingGlassIcon className="relative left-7 top-2 transform -translate-y-1/2"/>
<Input
placeholder="Filter categories..."
value={(table.getColumn("category")?.getFilterValue() as string) ?? ""}
onChange={(event) =>
table.getColumn("category")?.setFilterValue(event.target.value)
}
className="max-w-sm pl-10"
/>
</div>
I wrapped the input inside a div and placed the icon as a sibling to the input, using position relative (to the parent div) and just fine tune the position. This is my workaround this.
<div className="flex items-center py-4"> <MagnifyingGlassIcon className="relative left-7 top-2 transform -translate-y-1/2"/> <Input placeholder="Filter categories..." value={(table.getColumn("category")?.getFilterValue() as string) ?? ""} onChange={(event) => table.getColumn("category")?.setFilterValue(event.target.value) } className=" pl-10 max-w-sm" /> </div>
Thank you so much @Labastidaa
For a reason this solution was messing up with my flex
parent container.
Here's my workaround for people with the same issue as mine
<div className="relative flex items-center max-w-2xl ">
<MagnifyingGlassIcon className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 transform" />
<Input
placeholder="Your search..."
value={search}
onChange={(event) => setSearch(event.target.value)}
className=" pl-8"
/>
</div>
This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.
Not complete Mr Bot!
I'll add this as an example.
Please add this feature as soon as possible! This is such a common thing and it's needed most of the time. The hack of wrapping the input component with a div has many problems.
I've been using these as alternatives:
<div class="relative w-full">
<Input class="pl-9" placeholder="Type something..." />
<Search class="absolute left-0 top-0 m-2.5 h-4 w-4 text-muted-foreground"/>
</div>
<div class="relative w-full">
<Input class="pr-9" placeholder="Type something..." />
<Search class="absolute right-0 top-0 m-2.5 h-4 w-4 text-muted-foreground"/>
</div>
The hack of wrapping the input component with a div has many problems.
@chinmayghule afaik there is no other way of doing this. other ui libraries do exactly the same to put icons inside input fields.
If you inspect these examples, you'll see all icons are using position: absolute
- https://nextui.org/docs/components/input#password-input
- https://mantine.dev/core/input/#left-and-right-sections
Something like that works pretty good for me:
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {
className?: string;
icon?: React.ReactNode;
}
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
'p-3 hover:bg-primary-100 focus:bg-primary-50 data-[state=checked]:bg-primary-50 data-[state=checked]:hover:bg-primary-100',
'relative flex w-full cursor-default select-none items-center pl-8 outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>
{props.icon ? (
<span className="flex ">
<span className="h-9 w-9">{props.icon}</span>
<span className="ml-4">{children}</span>
</span>
) : (
children
)}
</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;
I've been using these as alternatives:
<div class="relative w-full"> <Input class="pl-9" placeholder="Type something..." /> <Search class="absolute left-0 top-0 m-2.5 h-4 w-4 text-muted-foreground"/> </div> <div class="relative w-full"> <Input class="pr-9" placeholder="Type something..." /> <Search class="absolute right-0 top-0 m-2.5 h-4 w-4 text-muted-foreground"/> </div>
thanks bro.
Hack with position:absolute
this is a bad way for number type input, as example
Hack with
position:absolute
this is a bad way for number type input, as example
You can easily fix this by adding a right-padding to the input.
I would be interested in knowing how you would implement it if not with position absolute
Hack with
position:absolute
this is a bad way for number type input, as exampleYou can easily fix this by adding a right-padding to the input.
I would be interested in knowing how you would implement it if not with position absolute
For example, like in Next UI, which you mentioned earlier https://nextui.org/docs/components/input#start--end-content
I see they are using a surrounding div to "simulate" the input background. For me personally, this would require too many changes in the input component, i.e. changing the background of the div and handling focus & hover states etc. to be feasible.
I don't see why using the position absolute variant wouldn't be enough; It just keeps things simpler.
Again, this is just personal preference, feel free to implement it like NextUI did
I see they are using a surrounding div to "simulate" the input background. For me personally, this would require too many changes in the input component, i.e. changing the background of the div and handling focus & hover states etc. to be feasible.
I don't see why using the position absolute variant wouldn't be enough; It just keeps things simpler.
Again, this is just personal preference, feel free to implement it like NextUI did
Thank you for your time
yes, the essence of my message was that position:absolute
in my opinion, is not an ideal solution, rather for some cases
This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.
I was having a problem with adding a icon inside a shadcn form input, so here it is
type Props = {
control: any;
label?: string;
hint?: string;
placeholder?: string;
name: string;
type?: string;
secureTextEntry?: boolean;
rightIcon?: any;
};
const FormInput = ({
control,
label,
hint,
placeholder,
name,
type = "text",
secureTextEntry,
rightIcon,
}: Props) => {
const secureEntry = useBoolean(true);
const IconComponent = rightIcon;
const iconClassName =
"w-5 absolute right-0 top-0 m-2.5 h-4 w-4 text-muted-foreground user-select-none cursor-pointer";
return (
<FormField
control={control}
name={name}
render={({ field }) => (
<FormItem>
<FormLabel>{label}</FormLabel>
<div className="relative w-full">
<FormControl>
<Input
className="pr-9"
type={secureTextEntry && secureEntry.value ? "password" : type}
placeholder={placeholder}
{...field}
/>
</FormControl>
{secureTextEntry &&
(secureEntry.value ? (
<Eye onClick={secureEntry.toggle} className={iconClassName} />
) : (
<EyeOff
onClick={secureEntry.toggle}
className={iconClassName}
/>
))}
{!secureTextEntry && rightIcon && (
<IconComponent className={iconClassName} />
)}
</div>
<FormDescription>{hint}</FormDescription>
<FormMessage />
</FormItem>
)}
/>
);
};
So is there an official example for this? 😇