Installation
Copy and paste the following code into your project.
npm i react-icon-cloud
components/magicui/icon-cloud.tsx
"use client";
import { useTheme } from "next-themes";
import { useEffect, useMemo, useState } from "react";
import {
Cloud,
fetchSimpleIcons,
ICloud,
renderSimpleIcon,
SimpleIcon,
} from "react-icon-cloud";
export const cloudProps: Omit<ICloud, "children"> = {
containerProps: {
style: {
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "100%",
paddingTop: 40,
},
},
options: {
reverse: true,
depth: 1,
wheelZoom: false,
imageScale: 2,
activeCursor: "default",
tooltip: "native",
initial: [0.1, -0.1],
clickToFront: 500,
tooltipDelay: 0,
outlineColour: "#0000",
maxSpeed: 0.04,
minSpeed: 0.02,
// dragControl: false,
},
};
export const renderCustomIcon = (icon: SimpleIcon, theme: string) => {
const bgHex = theme === "light" ? "#f3f2ef" : "#080510";
const fallbackHex = theme === "light" ? "#6e6e73" : "#ffffff";
const minContrastRatio = theme === "dark" ? 2 : 1.2;
return renderSimpleIcon({
icon,
bgHex,
fallbackHex,
minContrastRatio,
size: 42,
aProps: {
href: undefined,
target: undefined,
rel: undefined,
onClick: (e: any) => e.preventDefault(),
},
});
};
export type DynamicCloudProps = {
iconSlugs: string[];
};
type IconData = Awaited<ReturnType<typeof fetchSimpleIcons>>;
export default function IconCloud({ iconSlugs }: DynamicCloudProps) {
const [data, setData] = useState<IconData | null>(null);
const { theme } = useTheme();
useEffect(() => {
fetchSimpleIcons({ slugs: iconSlugs }).then(setData);
}, [iconSlugs]);
const renderedIcons = useMemo(() => {
if (!data) return null;
return Object.values(data.simpleIcons).map((icon) =>
renderCustomIcon(icon, theme || "light"),
);
}, [data, theme]);
return (
// @ts-ignore
<Cloud {...cloudProps}>
<>{renderedIcons}</>
</Cloud>
);
}
⚠️ Warning
Avoid using the IconCloud component in parent components where the component interacts with hooks or undergoes frequent state changes. Such interactions may lead to unexpected behavior, such as continuous spinning. Consider creating a separate component for the section of your application that utilizes hooks or undergoes frequent state changes in parent component.
Props
IconCloud
Displays a dynamic cloud of icons from the Simple Icons library based on provided slugs.
Prop | type | default | description |
---|---|---|---|
iconSlugs | string[] | An array of icon slugs corresponding to the icons you want to display. Each slug should match a supported icon from the Simple Icons library. |
Cloud
There are a number of options for modifying the way the cloud looks and behaves. Go to https://www.goat1000.com/tagcanvas-options.php to see the list of all available options for your cloud.
Prop | type | default | description |
---|---|---|---|
canvasProps | HTMLAttributes < HTMLCanvasElement > | undefined | Attributes that will be passed to the underlying canvas element | |
children | Tag[] | [] | Tags rendered using the provided renderers |
containerProps | HTMLAttributes < HTMLDivElement > | undefined | Attributes passed to the root div element | |
id | string | number | undefined | uuid | Should be provided when using SSR |
maxSpeed | int | 0.04 | To adjust the rotation speed in idle state |
minSpeed | int | 0.02 | To adjust the rotation speed when hovering |
dragControl | boolean | false | Enable or disable the ability to drag and interact with the icon cloud. |
dragThreshold | number | 4 | The number of pixels that the cursor must move to count as a drag instead of a click. |
decel | number | 0.95 | Deceleration rate when mouse leaves canvas. |
freezeDecel | boolean | false | Whether to freeze the cloud when dragging stops. |
renderSimpleIcon
Used to create a tag for the Cloud component
Prop | type | default | description |
---|---|---|---|
aProps | HTMLAttributes < HTMLAnchorElement > | undefined | Attributes passed to the underlying anchor element | |
bgHex | string | undefined | '#fff' | The string hex of the background the icon will be rendered on. Ex: '#fff'. Used to determine if the min contrast ratio for the icons default color will be met |
fallbackHex | string | undefined | '#000' | The color of the icon if the minContrastRatio is not met Ex: '#000' |
icon | any | undefined | The simple icon object you would like to render. Ex: import icon from "simple-icons/icons/javascript"; |
imgProps | HTMLAttributes < HTMLImageElement > | undefined | Attributes passed to the underlying img element | |
minContrastRatio | number | undefined | 1 | 0 - 21 The min contrast ratio between icon and bgHex before the fallbackHex will be used for the icon color |
size | number | undefined | 42 | The size in px of the icon |
fetchSimpleIcons
Used when you cant statically import simple icons during built time. Calling this will use fetch
to get icons for each provided slug.
Prop | type | default | description |
---|---|---|---|
slugs | string[] | Slugs to fetch svgs and colors for. The return icons may be passed to renderSimpleIcon |
Credits
- Credits to (https://github.com/teaguestockwell/react-icon-cloud)