npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

babel-plugin-jsx-map-class-props

v1.0.0

Published

Merges class names from any attribute with className or other compatible attributes.

Readme

babel-plugin-jsx-map-class-props

Travis build status NPM version

Merges class names from any attribute with className or other compatible attributes.

Installation

When babel-plugin-jsx-map-class-props cannot resolve attribute value at compile time, it imports helper functions (read Runtime attribute value formatting and merging). Therefore, you must install babel-plugin-jsx-map-class-props as a direct dependency of the project.

npm install babel-plugin-jsx-map-class-props --save

Why?

The idea was born when I tried to identify the components in our E2E tests. First of all I tried to find a property that most components pass to the DOM. I read about testId, data-test-id and some others, but our components library isn't aware of any of them. Then I thought about className. It is supported by most components. But we use CSS-modules, which decorates the class names, and so they cannot be simply recognized by e2e test. So we have to use additional classes for tests and combine them with the existing ones, and that makes a mess. Also we need to strip them in production. Finally, the combination of both directions gave me a new idea: i could put an identifier into a different property and merge it with the className at compile time. It also solved the issue of stripping these properties for production.

Configuration

Configure the options for the plugin within your .babelrc as follows:

{
  "plugins": [
    ["jsx-map-class-props", {
      "option": "value"
    }]
  ]
}

Options

|Name|Type|Description|Default| |---|---|---|---| |context|?string|Scoped names will be calculated relative to this path. |process.cwd()| |format|?GenerateScopedNameConfigurationType|Global pattern for class names formatting. Can be overridden by mapping option. Refer to Generating scoped names and Interpolate Name.|none| |clean|?boolean|Removes all matching props. This option can be used for removing debug/test classNames from production build. Can be overridden by mapping option. Ignored if false |false| |mappings|AttributeMappingType []|Array of attribute mapping options|[]|

Attribute Mapping Options

|Name|Type|Description|Default| |---|---|---|---| |format|?GenerateScopedNameConfigurationType|Pattern for class names formatting. Can override global option. Set null to prevent formatting. Refer to Generating scoped names and Interpolate Name. |none| |clean|?boolean|Removes all matching props. This option can be used for removing debug/test classNames from production build. Can override global option by being set to false explicitly.|none| |sourceName|?string|Name of an attribute to be matched.|| |sourceMask|?string|RegExp pattern string to find matching attributes. || |prefix|?string|String to find matching attributes by prefix. Target attribute's name will be calculated by removing prefix, if other options not specified.|| |targetName|?string|Name of the attribute the value will be merged with. This option has the highest priority for target calculation. Can be used with any source option.|| |targetMask|?string, ?function|Second parameter of String.replace. Can only be used with sourceMask, which will be used as a first parameter. Allows to calculate attribute name to merge value with.||

Missing a configuration? Raise an issue.

Allowed combinations of source-target options

(in priority order)

|Source|Target| Strategy Description| |---|---|---| |sourceName| targetName| match attribute by exact sourceName, merge with targetName attribute| |sourceMask| targetName| match attribute by sourceMask RegExp, merge with targetName attribute| |sourceMask| targetMask| match attribute by sourceMask RegExp, calculate target using foundName.replace(sourceMask, targetMask), merge with target attribute| |prefix| targetName| match attribute by prefix, merge with targetName attribute| |prefix| | match attribute by prefix, get target by stripping prefix, merge with target attribute|

Notes:

  • only one combination per mapping is allowed
  • other options will be ignored (according to priority)
  • if attribute is matched by a mapping, other mappings are ignored (in other words, an attribute can have only one target)

How does it work?

  1. Iterates through all JSX element declarations.
  2. Finds matched source attributes according to the mapping options.
    • If clean option is true, removes the source attribute that was found from the element and continues to the next iteration.
  3. Calculates target attribute names according to the mapping options.
  4. Formats source attribute value according to the mapping options:
    • If value is a string literal, generates a string literal value.
    • If value is a jSXExpressionContainer and format option is valid, uses a helper function (getClassName) to format value at runtime.
  5. Merges source attribute value with the target attribute:
    • If target attribute doesn't exist, moves formatted source attribute to the target.
    • If source and target values are a string literal, generates a string literal value.
    • If source or target value is a jSXExpressionContainer, uses a helper function (joinClassNames) to join values at runtime.
  6. Removes the source attribute from the element.

Runtime attribute value formatting and merging

When the value of a source attribute cannot be determined at compile time, babel-plugin-jsx-map-class-props uses getClassName helper function to format the value at runtime.

Input:

<div test-className={Math.random() > .5 ? 'a' : 'b'} />;

Output:

import _getClassName from 'babel-plugin-jsx-map-class-props/dist/browser/getClassName';

<div className={
  _getClassName(Math.random() > .5 ? 'a' : 'b', 'e2e-|')
} />;

When the value of a source or a target attribute cannot be determined at compile time, babel-plugin-jsx-map-class-props uses joinClassNames helper function to join the values at runtime.

Input:

<div test-className='my-component' className={styles.myComponent} />;

Output:

import _joinClassNames from 'babel-plugin-jsx-map-class-props/dist/browser/joinClassNames';

<div className={
  _joinClassNames('e2e-my-component', styles.myComponent)
} />;

Have a question or want to suggest an improvement?