Plugin transforming calls to class-bound-components
- Display Name Inlining: Infers implicit
displayName
values, e.g., looking at which variablesclassBound
components get assigned to and inlines these into the signatures. - Element Type Inlining: Replaces usage of the
Proxy
methods for intrinsic HTML elements (likeclassBound.div
,classBound.li
orclassBound.button
) to the primary signature to remove the runtime requirement ofProxy
TL;DR: If you don't want to type out the
displayName
for each call ofclassBound
but want a similar behavior to regular React functional component display names, use this transformation.
Usually, displayName
s in React benefit from the automatic assignment to Function.name
when defining a functional component, which will make the component appear as the name of the function in React DevTools and Error traces.
Unfortunately, this doesn't work for components created with classBound
, since these are defined in a closure. For this, all signatures of classBound
can be provided with an explicit string for the displayName
property of the component.
This babel transformation tries to infer the displayName
in the fashion like Function.name
would normally do and inlines these into the calls of classBound
.
Can be enabled (default) or disabled with the displayName
option, e.g.,
// .babelrc
{
"plugins": [
// ...
["babel-plugin-class-bound-components": {
"displayNames": true
}]
]
}
In
// input code
import classBound, { extend } from 'class-bound-components';
// These would appear as _Anonymous_ in React dev tools and error messages, since no explicit `displayName` argument is passed
const MyList = classBound.ul('myList', {
isWide: 'myList--wide',
});
const MyListItem = classBound.li('myListItem', {
isActive: 'myListItem--active',
});
const CustomList = extend(MyList, 'customList', {
isFlashy: 'customList--flashy',
});
const CompFropmOptions = classBound({
className: ['foo', 'bar'],
});
let foo = 'bar',
SomeComp = classBound('someComp');
Out
'use strict';
// output code
import classBound from 'class-bound-components';
// Babel plugin infers the `displayName` and explicitly inserts it into the signatures
const MyList = classBound('myList', 'MyList', {
isWide: 'myList--wide',
});
const MyListItem = classBound('myListItem', 'MyListItem', {
isWide: 'myListItem--wide',
});
const CustomList = extend(MyList, 'CustomList', 'customList', {
isFlashy: 'customList--flashy',
});
const CompFromOptions = classBound({
className: ['foo', 'bar'],
displayName: 'CompFromOptions',
});
let foo = 'bar',
SomeComp = classBound('someComp', 'SomeComp');
TL;DR: If you make use of the shorthand
classBound[JSX.IntrinsicElement]()
signature, e.g.,classBound.button
, and can't be sure ES6Proxy
is available in browsers (and don't want to polyfill it), use this transformation.
Beyond <div />
, classBound
can use any base element and even user land React components as a base type, which can be passed as the elementType
argument. For each intrinsic HTML element type, a method on classBound
is proxied for easier usage, like classBound.button('myButton')
or classBound.ul('myList')
. This functionality is backed by the ES6 Proxy
mechanism which is not available on IE11.
If you need to support IE11 or other outdated browsers not supporting Proxy
, enable this transformation. It replaces all calls of classBound[JSX.IntrinsicElement]()
in your sources with calls to the primary, Proxy
-less signature and inserts the desired element type as the elementType
Can be enabled (enabled) or disabled with the elementTypes
option, e.g.,
// .babelrc
{
"plugins": [
// ...
["babel-plugin-class-bound-components": {
"elementType": true
}]
]
}
In
// input code
import classBound, { extend } from 'class-bound-components';
// `classBound.ul` and `classBound.li` will error on outdated browsers, e.g., IE11
const MyList = classBound.ul('myList', { isWide: 'myList--wide' });
const MyListItem = classBound.li('myListItem');
Out
'use strict';
// output code
import classBound from 'class-bound-components';
// After transformation, `Proxy` is not made is of, so it also works on older browsers
const MyList = classBound('myList', null, { isWide: 'myList--wide' }, 'ul');
const MyListItem = classBound('myListItem', null, null, 'li');
$ npm install babel-plugin-class-bound-components
.babelrc
{
"plugins": [
[
"babel-plugin-class-bound-components",
{
"displayNames": true,
"elementTypes": true
}
]
]
}
$ babel --plugins class-bound-components script.js
require('babel-core').transform('code', {
plugins: [
[
'babel-plugin-class-bound-components',
{
displayNames: true,
elementTypes: true,
},
],
],
});
© 2021 Jannik Portz – License