7

I am trying to create a custom react component library using rollup, css-modules and tailwind css. The problem is when I try to install it into another react project the css from the style sheet is not loaded.

Folder structure is as below

src
 ┣ SimpleAlert
 ┃ ┣ SimpleAlert.js
 ┃ ┣ SimpleAlert.module.css
 ┃ ┗ styles.css
 ┣ assets
 ┃ ┗ tailwind.css
 ┗ index.js

My config is as below

rollup.config.js

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import postcss from "rollup-plugin-postcss";
import babel from "@rollup/plugin-babel";

const packageJson = require("./package.json");

export default {
    input: "src/index.js",
    output: [
        {
            file: packageJson.main,
            format: "cjs",
            sourcemap: true,
        },
        {
            file: packageJson.module,
            format: "esm",
            sourcemap: true,
        },
    ],
    plugins: [
        peerDepsExternal(),
        resolve(),
        // ref: https://stackoverflow.com/a/52885295
        babel({
            exclude: "node_modules/**",
            babelHelpers: "bundled",
        }),
        commonjs(),
        postcss({
            modules: true,
            plugins: [],
            extensions: [".css"],
        }),
    ],
};

postcss.config.js

module.exports = {
    plugins: [require("tailwindcss"), require("autoprefixer")],
};

package.json

{
    "name": "simple-react-alerts",
    "version": "1.0.0",
    "description": "Simple alert components for react",
    "main": "build/index.js",
    "module": "build/index.esm.js",
    "files": [
        "build"
    ],
    "repository": "git@github.com:Bsd15/simple-react-alerts.git",
    "author": "BSD",
    "license": "MIT",
    "private": false,
    "devDependencies": {
        "@babel/core": "^7.10.4",
        "@babel/preset-env": "^7.10.4",
        "@babel/preset-react": "^7.10.4",
        "@rollup/plugin-babel": "^5.0.4",
        "@rollup/plugin-commonjs": "^13.0.0",
        "@rollup/plugin-node-resolve": "^8.1.0",
        "babel-loader": "^8.1.0",
        "eslint": "^7.4.0",
        "eslint-plugin-react": "^7.20.3",
        "react": "^16.13.1",
        "react-dom": "^16.13.1",
        "rollup": "^2.21.0",
        "rollup-plugin-peer-deps-external": "^2.2.3",
        "rollup-plugin-postcss": "^3.1.2",
        "tailwindcss": "^1.4.6"
    },
    "peerDependencies": {
        "react": ">=16.8.0",
        "react-dom": ">=16.8.0",
        "tailwindcss": ">=1.4.6"
    },
    "scripts": {
        "build": "rollup -c",
        "build:css": " yarn tailwindcss build src/assets/tailwind.css -o src/SimpleAlert/index.css                                             "
    }
}

index.js

import SimpleAlert from "./SimpleAlert/SimpleAlert";
import { AlertType } from "./SimpleAlert/SimpleAlert";
import "./SimpleAlert/styles.css";
export { SimpleAlert, AlertType };

SimpleAlert.js

import React, { useState, useCallback } from "react";
import "./styles.css";
import classes from "./SimpleAlert.module.css";

export const AlertType = {
    Primary: "border-blue-500",
    Danger: "border-red-600",
    Info: "border-yellow-500",
    Success: "border-green-500",
};

const SimpleAlert = (WrappedComponent) => {
    const ComponentWithAlert = (props) => {
        const [show, setShow] = useState(false);
        const [alertHeading, setAlertHeading] = useState("");
        const [alertMessage, setAlertMessage] = useState("");
        const [alertBoxBorderClass, setalertBoxBorderClass] = useState(
            AlertType.Primary
        );

        const showAlertBox = useCallback(() => {
            setShow(true);
        }, []);

        const hideAlertBox = useCallback(() => {
            setShow(false);
        }, []);

        const showAlert = useCallback(
            (message, alertType, heading = "") => {
                if (message) {
                    setAlertMessage(message);
                    setalertBoxBorderClass(alertType);
                    setAlertHeading(heading);
                    showAlertBox();
                }
            },
            [showAlertBox, setAlertMessage, setalertBoxBorderClass, setAlertHeading]
        );

        const showTemporaryAlert = useCallback(
            (message, alertType, timeout = 5000, heading = "") => {
                if (message) {
                    setAlertMessage(message);
                    setalertBoxBorderClass(alertType);
                    setAlertHeading(heading);
                    showAlertBox();
                    setTimeout(() => {
                        hideAlertBox();
                    }, timeout);
                }
            },
            [
                showAlertBox,
                setAlertMessage,
                setalertBoxBorderClass,
                setAlertHeading,
                hideAlertBox,
            ]
        );

        return (
            <React.Fragment>
                <WrappedComponent
                    {...props}
                    showAlert={showAlert}
                    showTemporaryAlert={showTemporaryAlert}
                />
                <article
                    className={`fixed bottom-0 left-0 right-0 mx-auto container w-full lg:w-1/2 p-2 bg-white shadow-2xl border-t-8 ${alertBoxBorderClass} ${
                        classes.alertBox
                    } ${show ? classes.alertBoxShow : ""}`}
                >
                    <section id="content" className="flex flex-col items-center">
                        <section id="message" className="h-16 overflow-y-auto">
                            {alertHeading && (
                                <h1 className="font-bold text-lg">{alertHeading}</h1>
                            )}
                            <p>{alertMessage}</p>
                        </section>
                        <section id="close">
                            <button
                                className="bg-red-200 hover:bg-red-300 text-red-700 font-bold p-2 w-20"
                                onClick={hideAlertBox}
                            >
                                Close
                            </button>
                        </section>
                    </section>
                </article>
            </React.Fragment>
        );
    };
    return ComponentWithAlert;
};

export default SimpleAlert;

SimpleAlert.module.css

.alertBox {
    /* This timing applies on the way OUT */
    transition-timing-function: ease-in;

    /* Quick on the way out */
    transition: 0.2s;

    /* Hide thing by pushing it outside by default */
    transform: translateY(130%);
}

.alertBoxShow {
    /* This timing applies on the way IN */
    transition-timing-function: ease-out;

    /* A litttttle slower on the way in */
    transition: 0.25s;

    /* Move into place */
    transform: translateY(0);
}

The styles.css is generated using tailwindcss (which is 80k+ plus lines of css, and hence not posting)

The component is a hoc which can be used to overlap another component while exporting.

E.g as below

export default SimpleAlert(App)

The problem is the css present in styles.css. It's is not getting applied when the component library is installed into another react app as a dependency. The classes from SimpleAlert.module.css are getting loaded thought.

bsd
  • 133
  • 1
  • 2
  • 6
  • Same problem, did you solve it? – Marco Terzolo Mar 09 '21 at 07:02
  • 1
    Tried several things but nothing worked. I gave up and re-wrote the library using babel. I followed this guide https://hackernoon.com/creating-a-library-of-react-components-using-create-react-app-without-ejecting-d182df690c6b https://fathomtech.io/blog/create-a-react-component-library-using-create-react-app/ – bsd Mar 10 '21 at 17:39
  • Ah ok! No in the end i found out that i wasnt importing in html head the styles bundle that rollup serves unlinked :) so rollup still in game for now – Marco Terzolo Mar 11 '21 at 09:15
  • Hey, @MarcoTerzolo. Stumbled upon the same issue. How did you import the styles bundle that rollup serves up? – N Petterson Apr 04 '22 at 14:16
  • @NPetterson It was linked in html via tag. it was a css bundle so i needed to include it as any other css set. Hope it helps – Marco Terzolo Jun 10 '22 at 18:08

1 Answers1

3

Import styles bundle that rollup in the index.js or index.ts which is start file of main app. Like the following.

import "react-toggle-button/dist/esm/index.css";
Jakub Kurdziel
  • 3,216
  • 2
  • 12
  • 22
oyuka
  • 51
  • 5