refactor: Add NodeIcon component for displaying icons in GenericNode (#3459)

* feat: Add NodeIcon component for displaying icons in GenericNode

This commit adds a new component called NodeIcon to the GenericNode module. The NodeIcon component is responsible for displaying icons based on the data type of the node. It uses the nodeIconsLucide object from the styleUtils module to map the data type to the corresponding icon name. The component also handles the display of emojis as icons by checking if the icon is an emoji using the emoji-regex library. The icon color is determined based on the data type using the nodeColors object from the styleUtils module. The NodeIcon component is used in the GenericNode component to render the icon of the node.

* [autofix.ci] apply automated fixes

* feat: Remove useIconNodeRender hook from CustomNodes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
anovazzi1 2024-08-21 11:29:57 -03:00 committed by GitHub
commit 767a1a68b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 42 additions and 77 deletions

View file

@ -0,0 +1,34 @@
import { useTypesStore } from "@/stores/typesStore";
import { nodeColors, nodeIconsLucide } from "@/utils/styleUtils";
import emojiRegex from "emoji-regex";
import IconComponent from "../../../../components/genericIconComponent";
export function NodeIcon({
icon,
dataType,
showNode,
isGroup,
}: {
icon?: string;
dataType: string;
showNode: boolean;
isGroup?: boolean;
}) {
const types = useTypesStore((state) => state.types);
const name = nodeIconsLucide[dataType] ? dataType : types[dataType];
const isEmoji = emojiRegex().test(icon ?? "");
const iconColor = nodeColors[types[dataType]];
const iconName = icon || (isGroup ? "group_components" : name);
const iconClassName = `generic-node-icon ${
!showNode ? " absolute inset-x-6 h-12 w-12 " : ""
}`;
return icon && isEmoji ? (
<span className="text-lg">{icon}</span>
) : (
<IconComponent
name={iconName}
className={iconClassName}
iconColor={iconColor}
/>
);
}

View file

@ -1,4 +1,3 @@
import emojiRegex from "emoji-regex";
import { useEffect, useMemo, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
@ -18,13 +17,11 @@ import { useTypesStore } from "../../stores/typesStore";
import { OutputFieldType } from "../../types/api";
import { NodeDataType } from "../../types/flow";
import { scapedJSONStringfy } from "../../utils/reactflowUtils";
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
import { nodeIconsLucide } from "../../utils/styleUtils";
import { classNames, cn } from "../../utils/utils";
import { countHandlesFn } from "../helpers/count-handles";
import { getNodeInputColors } from "../helpers/get-node-input-colors";
import { getNodeOutputColors } from "../helpers/get-node-output-colors";
import useCheckCodeValidity from "../hooks/use-check-code-validity";
import useIconNodeRender from "../hooks/use-icon-render";
import useUpdateNodeCode from "../hooks/use-update-node-code";
import getFieldTitle from "../utils/get-field-title";
import sortFields from "../utils/sort-fields";
@ -33,6 +30,7 @@ import NodeInputField from "./components/NodeInputField";
import NodeName from "./components/NodeName";
import NodeOutputField from "./components/NodeOutputfield";
import NodeStatus from "./components/NodeStatus";
import { NodeIcon } from "./components/nodeIcon";
export default function GenericNode({
data,
@ -66,22 +64,6 @@ export default function GenericNode({
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
const nodeIconFragment = (icon) => {
return <span className="text-lg">{icon}</span>;
};
const checkNodeIconFragment = (iconColor, iconName, iconClassName) => {
return (
<IconComponent
name={iconName}
className={iconClassName}
iconColor={iconColor}
/>
);
};
const isEmoji = emojiRegex().test(data?.node?.icon!);
if (!data.node!.template) {
setErrorData({
title: `Error in component ${data.node!.display_name}`,
@ -96,17 +78,6 @@ export default function GenericNode({
useCheckCodeValidity(data, templates, setIsOutdated, setIsUserEdited, types);
const iconNodeRender = useIconNodeRender(
data,
types,
nodeColors,
name,
showNode,
isEmoji,
nodeIconFragment,
checkNodeIconFragment,
);
useEffect(() => {
setShowNode(data.showNode ?? true);
}, [data.showNode]);
@ -316,7 +287,12 @@ export default function GenericNode({
}
data-testid="generic-node-title-arrangement"
>
{iconNodeRender()}
<NodeIcon
dataType={data.type}
showNode={showNode}
icon={data.node?.icon}
isGroup={!!data.node?.flow}
/>
{showNode && (
<div className="generic-node-tooltip-div">
<NodeName

View file

@ -1,45 +0,0 @@
import { useCallback } from "react";
import { NodeDataType } from "../../types/flow";
const useIconNodeRender = (
data: NodeDataType,
types: { [key: string]: string },
nodeColors: { [key: string]: string },
name: string,
showNode: boolean,
isEmoji: boolean,
nodeIconFragment: (iconElement: string) => JSX.Element,
checkNodeIconFragment: (
iconColor: string,
iconName: string,
iconClassName: string,
) => JSX.Element,
) => {
const iconNodeRender = useCallback(() => {
const iconElement = data?.node?.icon;
const iconColor = nodeColors[types[data.type]];
const iconName =
iconElement || (data.node?.flow ? "group_components" : name);
const iconClassName = `generic-node-icon ${
!showNode ? " absolute inset-x-6 h-12 w-12 " : ""
}`;
if (iconElement && isEmoji) {
return nodeIconFragment(iconElement);
} else {
return checkNodeIconFragment(iconColor, iconName, iconClassName);
}
}, [
data,
types,
nodeColors,
name,
showNode,
isEmoji,
nodeIconFragment,
checkNodeIconFragment,
]);
return iconNodeRender;
};
export default useIconNodeRender;