MCPcopy
hub / github.com/gajus/react-css-modules

github.com/gajus/react-css-modules @v4.7.11 sqlite

repository ↗ · DeepWiki ↗ · release v4.7.11 ↗
27 symbols 75 edges 17 files 0 documented · 0%
README

React CSS Modules

GitSpo Mentions Travis build status NPM version js-canonical-style

React CSS Modules implement automatic mapping of CSS modules. Every CSS class is assigned a local-scoped identifier with a global unique name. CSS Modules enable a modular and reusable CSS!

⚠️⚠️⚠️ DEPRECATION NOTICE ⚠️⚠️⚠️

If you are considering to use react-css-modules, evaluate if babel-plugin-react-css-modules covers your use case. babel-plugin-react-css-modules is a lightweight alternative of react-css-modules.

babel-plugin-react-css-modules is not a drop-in replacement and does not cover all the use cases of react-css-modules. However, it has a lot smaller performance overhead (0-10% vs +50%; see Performance) and a lot smaller size footprint (less than 2kb vs +17kb).

It is easy to get started! See the demo https://github.com/gajus/babel-plugin-react-css-modules/tree/master/demo

CSS Modules

CSS Modules are awesome. If you are not familiar with CSS Modules, it is a concept of using a module bundler such as webpack to load CSS scoped to a particular document. CSS module loader will generate a unique name for each CSS class at the time of loading the CSS document (Interoperable CSS to be precise). To see CSS Modules in practice, webpack-demo.

In the context of React, CSS Modules look like this:

import React from 'react';
import styles from './table.css';

export default class Table extends React.Component {
    render () {
        return 







A0




B0







;
    }
}

Rendering the component will produce a markup similar to:









A0




B0








and a corresponding CSS file that matches those CSS classes.

Awesome!

webpack css-loader

CSS Modules is a specification that can be implemented in multiple ways. react-css-modules leverages the existing CSS Modules implementation webpack css-loader.

What's the Problem?

webpack css-loader itself has several disadvantages:

  • You have to use camelCase CSS class names.
  • You have to use styles object whenever constructing a className.
  • Mixing CSS Modules and global CSS classes is cumbersome.
  • Reference to an undefined CSS Module resolves to undefined without a warning.

React CSS Modules component automates loading of CSS Modules using styleName property, e.g.

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';

class Table extends React.Component {
    render () {
        return 







A0




B0







;
    }
}

export default CSSModules(Table, styles);

Using react-css-modules:

  • You are not forced to use the camelCase naming convention.
  • You do not need to refer to the styles object every time you use a CSS Module.
  • There is clear distinction between global CSS and CSS Modules, e.g.





  • You are warned when styleName refers to an undefined CSS Module (handleNotFoundStyleName option).
  • You can enforce use of a single CSS module per ReactElement (allowMultiple option).

The Implementation

react-css-modules extends render method of the target component. It will use the value of styleName to look for CSS Modules in the associated styles object and will append the matching unique CSS class names to the ReactElement className property value.

Awesome!

Usage

Setup consists of:

Module Bundler

webpack

Development

In development environment, you want to Enable Sourcemaps and webpack Hot Module Replacement (HMR). style-loader already supports HMR. Therefore, Hot Module Replacement will work out of the box.

Setup:

{
    test: /\.css$/,
    loaders: [
        'style-loader?sourceMap',
        'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
    ]
}
Production

In production environment, you want to extract chunks of CSS into a single stylesheet file.

Advantages:

  • Fewer style tags (older IE has a limit)
  • CSS SourceMap (with devtool: "source-map" and css-loader?sourceMap)
  • CSS requested in parallel
  • CSS cached separate
  • Faster runtime (less code and DOM operations)

Caveats:

  • Additional HTTP request
  • Longer compilation time
  • More complex configuration
  • No runtime public path modification
  • No Hot Module Replacement

– extract-text-webpack-plugin

Setup:

  • Install style-loader.
  • Install css-loader.
  • Use extract-text-webpack-plugin to extract chunks of CSS into a single stylesheet.

  • Setup /\.css$/ loader:

  • ExtractTextPlugin v1x:

    js { test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]') }

  • ExtractTextPlugin v2x:

    js { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?modules,localIdentName="[name]-[local]-[hash:base64:6]"' }), }

  • Setup extract-text-webpack-plugin plugin:

  • ExtractTextPlugin v1x:

    js new ExtractTextPlugin('app.css', { allChunks: true })

  • ExtractTextPlugin v2x:

    js new ExtractTextPlugin({ filename: 'app.css', allChunks: true })

Refer to webpack-demo or react-css-modules-examples for an example of a complete setup.

Browserify

Refer to css-modulesify.

Extending Component Styles

Use styles property to overwrite the default component styles.

Explanation using Table component:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';

class Table extends React.Component {
    render () {
        return 







A0




B0







;
    }
}

export default CSSModules(Table, styles);

In this example, CSSModules is used to decorate Table component using ./table.css CSS Modules. When Table component is rendered, it will use the properties of the styles object to construct className values.

Using styles property you can overwrite the default component styles object, e.g.

import customStyles from './table-custom-styles.css';

<Table styles={customStyles} />;

Interoperable CSS can extend other ICSS. Use this feature to extend default styles, e.g.

/* table-custom-styles.css */
.table {
    composes: table from './table.css';
}

.row {
    composes: row from './table.css';
}

/* .cell {
    composes: cell from './table.css';
} */

.table {
    width: 400px;
}

.cell {
    float: left; width: 154px; background: #eee; padding: 10px; margin: 10px 0 10px 10px;
}

In this example, table-custom-styles.css selectively extends table.css (the default styles of Table component).

Refer to the UsingStylesProperty example for an example of a working implementation.

styles Property

Decorated components inherit styles property that describes the mapping between CSS modules and CSS classes.

class extends React.Component {
    render () {















;
    }
}

In the above example, styleName='foo' and className={this.props.styles.foo} are equivalent.

styles property is designed to enable component decoration of Loops and Child Components.

Loops and Child Components

styleName cannot be used to define styles of a ReactElement that will be generated by another component, e.g.

import React from 'react';
import CSSModules from 'react-css-modules';
import List from './List';
import styles from './table.css';

class CustomList extends React.Component {
    render () {
        let itemTemplate;

        itemTemplate = (name) => {
            return <li styleName='item-template'>{name}</li>;
        };

        return <List itemTemplate={itemTemplate} />;
    }
}

export default CSSModules(CustomList, styles);

The above example will not work. CSSModules is used to decorate CustomList component. However, it is the List component that will render itemTemplate.

For that purpose, the decorated component inherits styles property that you can use just as a regular CSS Modules object. The earlier example can be therefore rewritten to:

import React from 'react';
import CSSModules from 'react-css-modules';
import List from './List';
import styles from './table.css';

class CustomList extends React.Component {
    render () {
        let itemTemplate;

        itemTemplate = (name) => {
            return <li className={this.props.styles['item-template']}>{name}</li>;
        };

        return <List itemTemplate={itemTemplate} />;
    }
}

export default CSSModules(CustomList, styles);

You can use styleName property within the child component if you decorate the child component using CSSModules before passing it to the rendering component, e.g.

import React from 'react';
import CSSModules from 'react-css-modules';
import List from './List';
import styles from './table.css';

class CustomList extends React.Component {
    render () {
        let itemTemplate;

        itemTemplate = (name) => {
            return <li styleName='item-template'>{name}</li>;
        };

        itemTemplate = CSSModules(itemTemplate, this.props.styles);

        return <List itemTemplate={itemTemplate} />;
    }
}

export default CSSModules(CustomList, styles);

Decorator

/**
 * @typedef CSSModules~Options
 * @see {@link https://github.com/gajus/react-css-modules#options}
 * @property {Boolean} allowMultiple
 * @property {String} handleNotFoundStyleName
 */

/**
 * @param {Function} Component
 * @param {Object} defaultStyles CSS Modules class map.
 * @param {CSSModules~Options} options
 * @return {Function}
 */

You need to decorate your component using `reac

Core symbols most depended-on inside this repo

set
called by 4
src/SimpleMap.js
render
called by 4
tests/reactCssModules.js
get
called by 3
src/SimpleMap.js
functionConstructor
called by 2
src/index.js
linkArray
called by 2
src/linkClass.js
linkElement
called by 2
src/linkClass.js
isReactComponent
called by 1
src/index.js
decoratorConstructor
called by 1
src/index.js

Shape

Class 12
Method 8
Function 7

Languages

TypeScript100%

Modules by API surface

tests/reactCssModules.js5 symbols
src/SimpleMap.js5 symbols
tests/extendReactClass.js4 symbols
tests/linkClass.js3 symbols
src/index.js3 symbols
src/extendReactClass.js3 symbols
src/linkClass.js2 symbols
tests/wrapStatelessFunction.js1 symbols
src/wrapStatelessFunction.js1 symbols

Dependencies from manifests, versioned

babel-cli6.18.0 · 1×
babel-plugin-add-module-exports0.2.1 · 1×
babel-plugin-lodash3.2.9 · 1×
babel-plugin-transform-proto-to-assign6.9.0 · 1×
babel-preset-es20156.18.0 · 1×
babel-preset-react6.16.0 · 1×
babel-preset-stage-06.16.0 · 1×
babel-register6.18.0 · 1×
chai4.0.0-canary.1 · 1×
chai-spies0.7.1 · 1×
eslint3.10.0 · 1×
eslint-config-canonical5.5.0 · 1×

For agents

$ claude mcp add react-css-modules \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact