ui icon indicating copy to clipboard operation
ui copied to clipboard

How to use a different icon in accordion and make it rotate.

Open joshwisehub opened this issue 1 year ago • 5 comments

I need help how to customize the accordion component icon.

joshwisehub avatar Jun 29 '23 16:06 joshwisehub

You can change the Accordion icon by changing the icon component in the accordion.tsx file:

const AccordionTrigger = React.forwardRef<
  React.ElementRef<typeof AccordionPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Header className="flex">
    <AccordionPrimitive.Trigger
      ref={ref}
      className={cn(
        "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
        className
      )}
      {...props}
    >
      {children}
- <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
+ <NewIcon className="h-4 w-4 shrink-0 transition-transform duration-200" />
    </AccordionPrimitive.Trigger>
  </AccordionPrimitive.Header>
))

Set NewIcon to whatever icon component you like.

dan5py avatar Jun 29 '23 16:06 dan5py

if my icon is custom.meaning it is svg file,How can i achieve the same behavior or i need to make it a component first?

joshwisehub avatar Jun 30 '23 06:06 joshwisehub

You can either use the <img> tag or copy & paste the svg code directly in the accordion file and apply the same classes to the element.

I'm used to create components for icons but those are just personal preferences.

dan5py avatar Jun 30 '23 07:06 dan5py

`interface Props { size?: number; color?: string; className?: string; }

const Arrow = ({ size = 42, color = '#013047', className }: Props) => { return ( <svg width={size} height={size} viewBox="0 0 42 42" fill="none" stroke={color} xmlns="http://www.w3.org/2000/svg" className={className} > ); };

export default Arrow;

`

joshwisehub avatar Jun 30 '23 08:06 joshwisehub

Seems good to me.

dan5py avatar Jun 30 '23 08:06 dan5py

Guys is there any way of changing icons when the Item gets clicked? Like open folder icon vs close folder icon?

So I got it with a bit of a react state:

`` const AccordionTrigger = React.forwardRef< React.ElementRef<typeof AccordionPrimitive.Trigger>, React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>>(({ className, children, ...props }, ref) => {

const [isOpen, setIsOpen] = React.useState(false);

const handleToggle = () => {
  setIsOpen((prevIsOpen) => !prevIsOpen);
};

return (
  <AccordionPrimitive.Header className="flex">
    <AccordionPrimitive.Trigger
      ref={ref}
      className={cn(
        "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline",
        className
      )}
      {...props}
      onClick={handleToggle}
    >
      {children}
      {
        isOpen
          ? <FolderOpen className="h-4 w-4 shrink-0 transition-transform duration-200" />
          : <FolderClosed className="h-4 w-4 shrink-0 transition-transform duration-200" />
      }
    </AccordionPrimitive.Trigger>
  </AccordionPrimitive.Header>
)

}); ``

toty88 avatar Jul 12 '23 19:07 toty88

@toty88 I have been trying to do the same with useState, but there are a bunch of messy edge cases.

I have been experimenting with using the data attributes, with no luck:

          <>
            <MinusIcon className="h-4 w-4 shrink-0 transition-transform duration-200 data-[state=open]:hidden" />
            <PlusIcon className="h-4 w-4 shrink-0 transition-transform duration-200 data-[state=closed]:hidden" />
          </>

greynewell avatar Oct 25 '23 03:10 greynewell

@toty88 you can add the group tailwind class to the parent AccordionPrimitive.Trigger element, detailed here: https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state

My solution:

<MinusIcon className="h-4 w-4 shrink-0 transition-transform duration-200 group-data-[state=open]:hidden" />
<PlusIcon className="h-4 w-4 shrink-0 transition-transform duration-200 group-data-[state=closed]:hidden" />

For more info, see the answers on #1133

greynewell avatar Oct 25 '23 04:10 greynewell

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.

shadcn avatar Jun 21 '24 23:06 shadcn