Skip to content

CSS Modules superset adding Operators to retrieve the right Classes based on Props.

Notifications You must be signed in to change notification settings

marceloadsj/css-operators

Repository files navigation

CSS Operators

Work in Progress

A combination of a Postcss Plugin and Webpack Loader on top of CSS Modules to add operators to CSS.


CSS Module

/* Button.module.css */

.Button {
  border-radius: 10px;

  (variant = primary) {
    background-color: blue;
    color: white;
  }

  (variant = secondary) {
    background-color: lightblue;
    color: blue;
  }

  (size = 100) {
    padding: 3px 6px;
  }

  (size = 200) {
    padding: 6px 12px;
  }
}

Javascript

// React

import useCssProps from "css-operators/react";
import buttonClasses from "./Button.module.css";

function Button(props) {
  // The extra props will be deleted from the result object
  const cssProps = useCssProps("Button", buttonClasses, props);

  return <button {...cssProps} />;
}

function App() {
  return (
    <Button variant="primary" size={100}>
      Hello World
    </Button>
  );
}

OR

// Vanilla

import getClassName from "css-operators";
import buttonClasses from "./Button.module.css";

const className = getClassName("Button", buttonClasses, {
  variant: "primary",
  size: 100,
});

const button = document.createElement("button");

button.className = className;

Setup

// postcss.config.js

// postcss-nested is a required plugin and it needs to be added after the css-operators
module.exports = {
  plugins: ["css-operators/postcss-plugin", "postcss-nested"],
};
// Webpack (Next.js, Storybook, ...)

const injectCssOperators = require("css-operators/injectOnWebpack");

module.exports = {
  webpack(config) {
    injectCssOperators(config);

    return config;
  },
};

API

Operator Behavior Description JS Equivalent
= Equality Compare the stringfied version of two values ==
!= Inequality Compare the difference of two values, transforming bools and nums !==
> Greater than operator Compare the difference of two numeric values >
< Less than operator Compare the difference of two numeric values <
>= Greater than or equal operator Compare the difference of two numeric values >=
<= Less than or equal operator Compare the difference of two numeric values <=

import getClassName from "css-operators"

// cssKey as string - the base class of your .module.css file. The same file can have multiple of these.
// cssModule as object - the import of the .module.css file. It will be parsed on webpack to a better format.
// props as object - the props object to compare with the operators.

// className as string - returns the parsed class name;

const className = getClassName(cssKey, cssModule, props);

import useCssProps from "css-operators/react"

// arguments as the same of getClassName function

// cssProps as object - returns a shallow copied object with the className added and the used props deleted

const cssProps = useCssProps(cssKey, cssModule, props);

Misc

You can mix some approaches to create a good way to organize your styles.

Tailwind CSS

/* Button.module.css */

.Button {
  @apply rounded;

  (variant = primary) {
    @apply bg-blue-500 text-white;
  }

  (variant = secondary) {
    @apply bg-blue-100 text-blue-500;
  }

  (size = 100) {
    @apply px-3 py-2;
  }

  (size = 200) {
    @apply px-6 py-4;
  }
}

About

CSS Modules superset adding Operators to retrieve the right Classes based on Props.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published