Search code examples
javascriptreactjstypescriptionic-frameworkionic5

Ion-icon does not show when passed as a prop to another component


In my Dashboard Page, I have a component I'm rendering called <DashHome /> I passed in an array of objects as a prop to it from Dashboard Page which an icon is part of each object, everything get rendered except the icon, fortunately when I console.log() the icon, it gave me the name.

I don't know what is wrong, I'm I passing in the wrong icons? tested it with many icons tho. <IonIcon />

Dashboard.tsx

import {
  IonBackButton,
  IonButtons,
  IonContent,
  IonFab,
  IonFabButton,
  IonHeader,
  IonIcon,
  IonMenuButton,
  IonPage,
  IonTitle,
  IonToolbar,
  NavContext,
} from "@ionic/react";
import { addOutline, arrowBackOutline } from "ionicons/icons";
import { HiMenuAlt1 } from "react-icons/hi";
import React, { useContext } from "react";
import { useParams } from "react-router";
import DashHome from "../../components/DashHome/DashHome";
import "./Dashboard.css";
import DashProfile from "../../components/DashProfile/DashProfile";
import DashSettings from "../../components/DashSettings/DashSettings";
import NoOfPros from "../NoOfPros/NoOfPros";
import Edit from "../Edit/Edit";
import Draft from "../Draft/Draft";
import Converted from "../Converted/Converted";
import WorkingDays from "../WorkingDays/WorkingDays";
import Unsubmitted from "../Unsubmitted/Unsubmitted";

interface dashboard {
  title: string;
  amount: string;
  bg: string;
  link: string;
  icon: string;
}

const dashboards: dashboard[] = [
  {
    title: "No of Prospects",
    amount: "200",
    bg: "first",
    link: "/dashboard/Prospect",
    icon: "home",
  },
  {
    title: "No of Converted Prospect",
    amount: "700",
    bg: "second",
    link: "/dashboard/Converted Prospect",
    icon: "listOutline",
  },
  {
    title: "Days worked in the month",
    amount: "20",
    bg: "third",
    link: "/dashboard/Working Days",
    icon: "addOutline",
  },
  {
    title: "Unsubmitted Prospects",
    amount: "10",
    bg: "fourth",
    link: "/dashboard/Unsubmitted Prospect",
    icon: "calendarOutline",
  },
];

const Dashboard: React.FC = () => {
  const { name } = useParams<{ name: string }>();
  const { navigate } = useContext(NavContext);

  const goToProspect = () => {
    navigate("/create", "forward");
  };
  console.log(name);

  return (
    <IonPage className="dashboard">
      <IonHeader translucent={true} className="ion-no-border">
        <IonToolbar color="primary">
          <IonButtons slot="start">
            {name === "Home" ? (
              <IonMenuButton className="ion-menu-button">
                <HiMenuAlt1 stroke="1" color="#fff" />
              </IonMenuButton>
            ) : (
              <IonBackButton
                defaultHref="/dashboard/Home"
                icon={arrowBackOutline}
              />
            )}
          </IonButtons>
          <IonTitle color="#fff">
            {name === "Home" ? "Hi, John Doe" : name}
          </IonTitle>
        </IonToolbar>
      </IonHeader>

      <IonContent className="ion-padding content">
        {name === "Home" ? (
          <DashHome dashboards={dashboards} />
        ) : name === "Profile" ? (
          <DashProfile />
        ) : name === "Prospect" ? (
          <NoOfPros />
        ) : name === "Settings" ? (
          <DashSettings />
        ) : name === "Edit" ? (
          <Edit />
        ) : name === "Draft" ? (
          <Draft />
        ) : name === "Converted Prospect" ? (
          <Converted />
        ) : name === "Working Days" ? (
          <WorkingDays />
        ) : name === "Unsubmitted Prospect" ? (
          <Unsubmitted />
        ) : (
          <div>The Stufff</div>
        )}
      </IonContent>

      {name === "Home" && (
        <IonFab vertical="bottom" horizontal="end" slot="fixed">
          <IonFabButton onClick={() => goToProspect()}>
            <IonIcon icon={addOutline} />
          </IonFabButton>
        </IonFab>
      )}
    </IonPage>
  );
};

export default Dashboard;

DashHome.tsx

import React from "react";
import { IonCard, IonCol, IonGrid, IonIcon, IonRow } from "@ionic/react";
import "./DashHome.css";

interface dashboards {
  title: string;
  amount: string;
  bg: string;
  link: string;
  icon: string;
}

type Props = {
  dashboards: dashboards[];
};

const DashHome: React.FC<Props> = ({ dashboards }) => {
  return (
    <div>
      <IonGrid className="dash ion-no-padding">
        <IonRow className="ion-margin-top">
          {dashboards.map((board, idx) => (
            <IonCol size="6" className="ion-no-padding" key={idx}>
              <IonCard href={board.link} className="card" color={board.bg}>
                <div className="ion-margin-bottom ion-margin-top">
                  <IonIcon color="light" icon={board.icon} />
                  {console.log(board.icon)}
                </div>
                <h2 className="card-title">{board.title}</h2>
                <p className="card-text">{board.amount}</p>

                <IonIcon color="light" icon={board.icon} />
              </IonCard>
            </IonCol>
          ))}
        </IonRow>
      </IonGrid>

      <div className="sec-color">
        <p className="ml2 small">Get the most out of your performance</p>
        <IonCard className="card-no-bg bordered">
          <p className="sec-color l-h">5 Pending Prospect..</p>
        </IonCard>
      </div>
    </div>
  );
};

export default DashHome;

The problem is if I do <IonIcon icon={addOutline} /> for example, it will work.


Solution

  • Might be useful.

    it seems ion-icon does not like the icon in form of a string. I solved it by doing this:

    the type icon: string,

    import { addOutline } from "ionicons/icons";
    
    {
     ...
     icon: addOutline // just as imported instead of in string.
    }