Skip to content

Commit 0a1bdd1

Browse files
authored
Break out attribute coercion to its own package (#745)
* Break out attribute coercion to its own package * Fix function call * Update packages/babel-plugin-html-attributes-to-jsx/readme.md
1 parent ac7572d commit 0a1bdd1

File tree

5 files changed

+675
-0
lines changed

5 files changed

+675
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const styleToObject = require('style-to-object')
2+
const camelCaseCSS = require('camelcase-css')
3+
const t = require('@babel/types')
4+
const {paramCase: camelCase} = require('@mdx-js/util')
5+
6+
const TRANSLATIONS = require('./translations')
7+
8+
const propsKeysVisitor = {
9+
ObjectProperty(node) {
10+
if (node.node.key.extra.rawValue in TRANSLATIONS) {
11+
node.node.key.value =
12+
TRANSLATIONS[node.node.key.value] || node.node.key.value
13+
}
14+
}
15+
}
16+
17+
const jsxAttributeFromHTMLAttributeVisitor = {
18+
JSXAttribute(node) {
19+
if (node.node.name.name in TRANSLATIONS) {
20+
node.node.name.name = TRANSLATIONS[node.node.name.name]
21+
} else if (node.node.name.name === `props`) {
22+
node.traverse(propsKeysVisitor)
23+
} else if (
24+
node.node.name.name.includes(`-`) &&
25+
!node.node.name.name.startsWith(`data`) &&
26+
!node.node.name.name.startsWith(`aria`)
27+
) {
28+
node.node.name.name = camelCase(node.node.name.name)
29+
}
30+
31+
if (
32+
node.node.name.name === `style` &&
33+
node.node.value.type === `StringLiteral`
34+
// Node.node.value.type !== "JSXExpressionContainer"
35+
) {
36+
let styleArray = []
37+
styleToObject(node.node.value.extra.rawValue, function(name, value) {
38+
styleArray.push([camelCaseCSS(name), value])
39+
})
40+
node.node.value = t.jSXExpressionContainer(
41+
t.objectExpression(
42+
styleArray.map(([key, value]) =>
43+
t.objectProperty(t.stringLiteral(key), t.stringLiteral(value))
44+
)
45+
)
46+
)
47+
}
48+
}
49+
}
50+
51+
const babelPluginHtmlAttributesToJsx = () => {
52+
return {
53+
visitor: {
54+
JSXElement(path) {
55+
path.traverse(jsxAttributeFromHTMLAttributeVisitor)
56+
}
57+
}
58+
}
59+
}
60+
61+
module.exports = babelPluginHtmlAttributesToJsx
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "babel-plugin-html-attributes-to-jsx",
3+
"version": "1.3.1",
4+
"description": "Coerce HTML attributes into something JSX and React friendly",
5+
"license": "MIT",
6+
"keywords": [
7+
"mdx",
8+
"markdown",
9+
"react",
10+
"jsx",
11+
"remark",
12+
"babel"
13+
],
14+
"homepage": "https://mdxjs.com",
15+
"repository": "mdx-js/mdx",
16+
"bugs": "https://github.com/mdx-js/mdx/issues",
17+
"author": "Christopher Biscardi <[email protected]> (https://www.christopherbiscardi.com)",
18+
"contributors": [
19+
"Christopher Biscardi <[email protected]> (https://www.christopherbiscardi.com)",
20+
"John Otander <[email protected]> (http://johnotander.com)"
21+
],
22+
"files": [
23+
"index.js",
24+
"translations.js"
25+
],
26+
"dependencies": {
27+
"@babel/types": "^7.5.5",
28+
"@mdx-js/util": "^1.3.1",
29+
"camelcase-css": "^2.0.1",
30+
"style-to-object": "^0.2.3"
31+
},
32+
"devDependencies": {
33+
"@babel/core": "7.5.5",
34+
"@babel/preset-react": "7.0.0",
35+
"jest": "24.8.0"
36+
},
37+
"scripts": {
38+
"test": "jest"
39+
},
40+
"jest": {
41+
"testEnvironment": "node"
42+
}
43+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# `babel-plugin-html-attributes-to-jsx`
2+
3+
Coerce HTML attributes into something JSX and React
4+
friendly. Used by [MDX](https://mdxjs.com).
5+
6+
## Installation
7+
8+
```sh
9+
yarn add babel-plugin-html-attributes-to-jsx
10+
```
11+
12+
## Usage
13+
14+
```js
15+
const babel = require('@babel/core')
16+
17+
const plugin = require('babel-plugin-html-attributes-to-jsx')
18+
19+
const jsx = `
20+
export const Foo = () => (
21+
<div srcset="foo">
22+
<Button />
23+
</div>
24+
)
25+
`
26+
27+
const plugin = new BabelPluginHtmlAttributesToJsx()
28+
29+
const result = babel.transform(jsx, {
30+
configFile: false,
31+
plugins: [
32+
'@babel/plugin-syntax-jsx',
33+
plugin
34+
]
35+
})
36+
37+
console.log(result.code)
38+
```
39+
40+
### Input
41+
42+
```js
43+
export const Foo = () => (
44+
<div srcset="foo">
45+
<Button />
46+
</div>
47+
)
48+
```
49+
50+
### Output
51+
52+
```js
53+
const Foo = () => (
54+
<div srcSet="foo">
55+
<Button />
56+
</div>
57+
)
58+
```
59+
60+
## License
61+
62+
MIT
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const babel = require('@babel/core')
2+
3+
const plugin = require('..')
4+
5+
const testContents = `
6+
<img srcset="foo" />
7+
`
8+
const expectedResults = `React.createElement("img", {
9+
srcSet: "foo"
10+
});`
11+
12+
describe('babel-plugin-remove-export-keywords', () => {
13+
test('removes all export keywords', () => {
14+
const result = babel.transform(testContents, {
15+
configFile: false,
16+
plugins: [plugin],
17+
presets: [require('@babel/preset-react')]
18+
})
19+
20+
expect(result.code).toEqual(expectedResults)
21+
})
22+
})

0 commit comments

Comments
 (0)