skip to Main Content

I am working on creating a react component library using typescript and I am having problems using the components.

I currently only have a button component as I am just getting this project started. However, when I bundle with rollup and publish to npm (I am using github’s npm registry), and then install the package on a project, the onClick events do no work.

On click events function while testing within the library but once I try to use it as an actual package is when they no longer function.

Here is my current rollup config:

import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import dts from "rollup-plugin-dts";

import packageJson from "./package.json" assert { type: "json" };
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import postcss from "rollup-plugin-postcss";
import terser from "@rollup/plugin-terser";

export default [
  {
    input: "src/index.ts",
    output: [
      {
        file: packageJson.module,
        format: "esm",
        sourcemap: true,
      },
    ],
    plugins: [
      peerDepsExternal(),
      resolve(),
      commonjs(),
      typescript({ tsconfig: "./tsconfig.json" }),
      postcss({
        plugins: [],
      }),
      terser(),
    ],
  },
  {
    input: "dist/esm/types/index.d.ts",
    output: [{ file: "dist/index.d.ts", format: "esm" }],
    plugins: [dts()],
    external: [/.css$/],
  },
];

And here is my Button component:

import React from "react";

export interface ButtonProps {
  /**
   * The button lable.
   */
  variant?: "primary" | "secondary" | "danger" | "outline" | "ghost";
  /**
   * Is the button disabled?
   */
  disabled?: boolean;
  /**
   * Is Rounded?
   */
  rounded?: boolean;
  /**
   * Theme variant.
   */
  theme?: "dark" | "light";
  /**
   * Any children.
   */
  children?: any;
  /**
   * Size type.
   */
  size?: "small" | "normal" | "large" | "icon";
  /**
   * On click action.
   */
  onClick?: () => void;
}

const Button = ({
  disabled = false,
  variant = "primary",
  rounded = true,
  theme = "dark",
  children,
  size = "normal",
  onClick = () => {},
}: ButtonProps) => {
  let variantStyle = "";
  switch (variant) {
    case "primary":
      if (theme === "dark") {
        variantStyle = "bg-slate-100 text-slate-900 hover:enabled:bg-slate-300";
      } else {
        variantStyle = "bg-slate-900 text-slate-200 hover:enabled:bg-slate-700";
      }
      break;
    case "secondary":
      if (theme === "dark") {
        variantStyle = "bg-slate-500 text-slate-100 hover:enabled:bg-slate-400";
      } else {
        variantStyle = "bg-slate-300 text-slate-900 hover:enabled:bg-slate-100";
      }
      break;
    case "danger":
      variantStyle = "bg-rose-600 text-slate-100 hover:enabled:bg-rose-400";
      break;
    case "outline":
      if (theme === "dark") {
        variantStyle =
          "border-2 border-slate-100 text-slate-100 hover:enabled:bg-slate-100 hover:enabled:text-slate-900";
      } else {
        variantStyle =
          "border-2 border-slate-900 text-slate-900 hover:enabled:bg-slate-900 hover:enabled:text-slate-100";
      }
      break;
    case "ghost":
      if (theme === "dark") {
        variantStyle =
          "text-slate-100 hover:enabled:bg-slate-100 hover:enabled:text-slate-900";
      } else {
        variantStyle =
          "text-slate-900 hover:enabled:bg-slate-900 hover:enabled:text-slate-100";
      }
      break;
    default:
      if (theme === "dark") {
        variantStyle = "bg-slate-100 text-slate-900 hover:enabled:bg-slate-300";
      } else {
        variantStyle = "bg-slate-900 text-slate-200 hover:enabled:bg-slate-700";
      }
      break;
  }

  let sizeStyle = "";
  switch (size) {
    case "small":
      sizeStyle = "px-2 py-1 text-xs";
      break;
    case "normal":
      sizeStyle = "px-4 py-2 text-base";
      break;
    case "large":
      sizeStyle = "px-8 py-4 text-xl";
      break;
    case "icon":
      sizeStyle = "px-2 py-2 text-base";
      break;
    default:
      sizeStyle = "px-4 py-2 text-base";
      break;
  }

  return (
    <button
      onClick={() => {
        onClick();
      }}
      className={`${variantStyle} ${sizeStyle} ${
        rounded ? "rounded-md" : ""
      } ease-in-out duration-300 p-2 disabled:opacity-50 
      flex flex-row justify-center items-center`}
      disabled={disabled}
    >
      {children}
    </button>
  );
};

export default Button;

If I simply copy the Button component code from the library and put it into a component file on whatever project I use it on, then the button functions as expected. The onClick function works. This is why I am led to believe that it is something with rollup.

This is how I am currently trying to implement the Button component:

<Button onClick={() => console.log("Test")} >Test Button</Button>

I have been scratching my head with this for a while now. Any help is extremely appreciated!

For further context of the project here is the repo for it:
MinUI

2

Answers


  1. Chosen as BEST ANSWER

    Found the solution.

    I had to change the onClick of the button tag from onClick={onClick} to

    onClick={() => {
        onClick?.();
    }}
    

  2. Try this way

        return (
         <button
           onClick={onClick}
           className={`${variantStyle} ${sizeStyle} ${
             rounded ? "rounded-md" : ""
           } ease-in-out duration-300 p-2 disabled:opacity-50 
           flex flex-row justify-center items-center`}
           disabled={disabled}
         >
           {children}
         </button>
      );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search