Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom React Component Library not loading CSS when installed as dependency in another react project

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": "[email protected]: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.

like image 379
bsd Avatar asked Jun 30 '26 00:06

bsd


1 Answers

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";
like image 108
oyuka Avatar answered Jul 01 '26 16:07

oyuka