diff --git a/README.md b/README.md
index 66a041a..dba103a 100644
--- a/README.md
+++ b/README.md
@@ -23,9 +23,7 @@ npm install --save-dev babel-plugin-transform-react-jsx
### Via `.babelrc` (Recommended)
-**.babelrc**
-
-Without options (no different from `transform-react-jsx`):
+#### Without options (no different from `transform-react-jsx`):
```json
{
@@ -33,15 +31,15 @@ Without options (no different from `transform-react-jsx`):
}
```
-With options:
+#### With options:
```json
{
"plugins": [
["transform-jsx-flexible", {
"tags": {
- "CustomTag1": "createElement_CustomTag1",
- "CustomTag2": "createElement_CustomTag2"
+ "somelib.CustomTag1": "createElement_CustomTag1",
+ "somelib.CustomTag2": "createElement_CustomTag2"
}
}]
]
@@ -56,9 +54,9 @@ var profile =
{[user.firstName, user.lastName].join(' ')}
;
-var somethingElse =
+var somethingElse =
-;
+;
```
**Code Out**
@@ -69,7 +67,7 @@ var profile = React.createElement("div", null,
React.createElement("h3", null, [user.firstName, user.lastName].join(" "))
);
-var somethingElse = createElement_CustomTag1(CustomTag1, null,
+var somethingElse = createElement_CustomTag1(somelib.CustomTag1, null,
createElement_CustomTag1("div", null)
);
```
@@ -107,18 +105,22 @@ For example:
"transform-jsx-flexible",
{
"tags": {
- "CustomTag1": "createElement_CustomTag1",
- "CustomTag2": "createElement_CustomTag2"
+ "somelib.CustomTag1": "createElement_CustomTag1",
+ "somelib.CustomTag2": "createElement_CustomTag2"
}
}
]
```
-Using this configuration, any `CustomTag1` element and any JSX elements
+Using this configuration, any `somelib.CustomTag1` element and any JSX elements
enclosed inside of it will be created using the function
`createElement_CustomTag1()` in the transpiled JS code, instead of
`React.createElement` (or the current default JSX function).
-The same goes for `CustomTag2` and `createElement_CustomTag2`. Also, JSX
-handlers can be changed within the same block by nesting these custom tags
+The same goes for `somelib.CustomTag2` and `createElement_CustomTag2`. Also,
+JSX handlers can be changed within the same block by nesting these custom tags
together.
+
+For clarity and explicitness, it's recommended, but not required, to specify
+any custom tags with a member expression (`somelib.CustomTag1` in the examples
+above), rather than simply a tag name.
diff --git a/index.js b/index.js
index df484f7..4c36f82 100644
--- a/index.js
+++ b/index.js
@@ -8,6 +8,18 @@ module.exports = function( { types: t } ) {
.reduce( ( object, property ) => t.memberExpression( object, property ) );
}
+ function getJSXMemberExpressionName( expr ) {
+ let namePieces = [];
+ if ( expr.object.object && expr.object.property ) {
+ namePieces = namePieces.concat(
+ getJSXMemberExpressionName( expr.object )
+ );
+ } else {
+ namePieces = namePieces.concat( expr.object.name );
+ }
+ return namePieces.concat( expr.property.name );
+ }
+
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
const visitor = helper( {
@@ -42,10 +54,20 @@ module.exports = function( { types: t } ) {
do {
const openingElement = currentPath.get( 'openingElement' );
if ( openingElement && openingElement.node ) {
- const nodeName = openingElement.node.name.name;
- if ( tagOptions[ nodeName ] ) {
+ const nodeNameExpr = openingElement.node.name;
+ let elementName;
+ if ( nodeNameExpr.type === 'JSXIdentifier' ) {
+ // A simple JSX expression like
+ elementName = nodeNameExpr.name;
+ } else if ( nodeNameExpr.type === 'JSXMemberExpression' ) {
+ // A JSX member expression like
+ elementName = getJSXMemberExpressionName( nodeNameExpr )
+ .join( '.' );
+ }
+
+ if ( tagOptions[ elementName ] ) {
jsxCurrentIdentifier = stringToCallExpression(
- tagOptions[ nodeName ]
+ tagOptions[ elementName ]
);
break;
}
diff --git a/test/fixtures/member-expression/member-expression/actual.js b/test/fixtures/member-expression/member-expression/actual.js
new file mode 100644
index 0000000..f27d96e
--- /dev/null
+++ b/test/fixtures/member-expression/member-expression/actual.js
@@ -0,0 +1,21 @@
+;
+
+;
+
+;
+
+;
+
+
+
+;
+
+;
diff --git a/test/fixtures/member-expression/member-expression/expected.js b/test/fixtures/member-expression/member-expression/expected.js
new file mode 100644
index 0000000..fc04c7c
--- /dev/null
+++ b/test/fixtures/member-expression/member-expression/expected.js
@@ -0,0 +1,15 @@
+createElement_CustomTag1(CustomTag1, null);
+
+React.createElement(CustomTag2, null);
+
+createElement_CustomTag2(namespaced.CustomTag2, null);
+
+somelib.createElement_CustomTag3(namespaced.rather.deeply.CustomTag3, null);
+
+somelib.createElement_CustomTag3(
+ namespaced.rather.deeply.CustomTag3,
+ null,
+ somelib.createElement_CustomTag3(WithSomeWhitespace, { because: "why not" })
+);
+
+React.createElement(Component, { prop: "foo" });
diff --git a/test/fixtures/member-expression/options.json b/test/fixtures/member-expression/options.json
new file mode 100644
index 0000000..a3ca7f0
--- /dev/null
+++ b/test/fixtures/member-expression/options.json
@@ -0,0 +1,14 @@
+{
+ "plugins": [
+ [
+ "transform-jsx-flexible", {
+ "tags": {
+ "CustomTag1": "createElement_CustomTag1",
+ "namespaced.CustomTag2": "createElement_CustomTag2",
+ "namespaced.rather.deeply.CustomTag3": "somelib.createElement_CustomTag3"
+ }
+ }
+ ]
+ ]
+}
+