magicuidesign / magicui

UI Library for Design Engineers. Animated components and effects you can copy and paste into your apps. Free. Open Source.
https://magicui.design
MIT License
11.71k stars 460 forks source link

clean up code for animated beam component #29

Open dillionverma opened 5 months ago

dillionverma commented 5 months ago

Feedback

image https://magicui.design/docs/components/animated-beam

TODO:

itsarghyadas commented 5 months ago

What naming convention do you think would be a better approach for the animated-beam component?

Ianduha13 commented 5 months ago

Hello everyone, I was trying some workarounds on this and i found that something like this could be an option:


export default function AnimatedBeamMultipleInputDemo() {
  const containerRef = useRef<HTMLDivElement>(null);

  const icons = [
    { component: <Icons.googleDrive className="h-6 w-6" /> },
    { component: <Icons.googleDocs className="h-6 w-6" /> },
    { component: <Icons.whatsapp className="h-6 w-6" /> },
    { component: <Icons.messenger className="h-6 w-6" /> },
    { component: <Icons.notion className="h-6 w-6" /> },
    { component: <Icons.openai className="h-16 w-16" /> },
    { component: <Icons.user className="text-black" /> },
  ];

  const refs = useRef<Array<React.RefObject<HTMLDivElement>>>(
    Array.from({ length: icons.length }, () => React.createRef()),
  );

  return (
    <div
      className="relative flex h-full w-full max-w-[32rem] items-center justify-center overflow-hidden rounded-lg border bg-background p-10 md:shadow-xl"
      ref={containerRef}
    >
      <div className="flex h-full w-full flex-row items-stretch justify-between gap-10">
        <div className="flex flex-col justify-center gap-2">
          {icons.slice(0, 5).map((icon, index) => (
            <Circle ref={refs.current[index]} key={index}>
              {icon.component}
            </Circle>
          ))}
        </div>
        <div className="flex flex-col justify-center">
          <Circle ref={refs.current[5]} className="h-16 w-16">
            {icons[5].component}
          </Circle>
        </div>
        <div className="flex flex-col justify-center">
          <Circle ref={refs.current[6]}>{icons[6].component}</Circle>
        </div>
      </div>

      {icons.slice(0, 5).map((_, index) => (
        <AnimatedBeam
          key={index}
          containerRef={containerRef}
          fromRef={refs.current[index]}
          toRef={refs.current[5]}
        />
      ))}
      <AnimatedBeam
        containerRef={containerRef}
        fromRef={refs.current[5]}
        toRef={refs.current[6]}
      />
    </div>
  );
} 

It does'nt finish to convince me because if the users modify the array to have 1 less item it should break, but suggestions and feedback are welcome.

Also I think is important to fix the list of icons at the end of each component. I can work on a minimal icon utility library to disponibilize the same icons used on the examples (telling the user that if they want they always can use any other library, and is based on lucide with some adittions for example purposes). It's only an idea too, if you consider it great create a repo and i will work in that there @dillionverma

dillionverma commented 5 months ago

this is a really good start

if i were to think about the developer experience for this i want to start backwards

i.e. how do i want to use this as a developer

here's a really rough idea of what I think would be convenient / nice (open to more ideas!)

<AnimatedBeam>
   <Circle1  />
   <Circle2 />
</AnimatedBeam>

This is great for a base case of connecting 2 circles but is not generalizable to all cases

Need to brainstorm more clever ways to make this work for N number of beams but not sure the best way yet

hope this gives some more ideas

dillionverma commented 5 months ago

Also agreed that fixing the list of icons would be amazing! what do you propose? I would personally stay away from making another repo since it's more maintenance - but a copy paste type of approach works well imo. maybe it's just an additional file we can guide users to install during setup?