Skip to content

Commit a2709d2

Browse files
committed
feat: transform block to attribute
1 parent 0cb224b commit a2709d2

File tree

6 files changed

+67
-1
lines changed

6 files changed

+67
-1
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ const Component = props => pug` //- const Component = props => (
114114
`;
115115
```
116116

117+
#### Transform block to attribute
118+
119+
```jsx
120+
const Component = props => pug` //- const Component = props => (
121+
Menu //- <Menu icon={<img />}>
122+
button //- <button />
123+
block icon //- </Menu>
124+
img //- )
125+
`;
126+
```
127+
117128
#### Interpolation
118129

119130
If you'd prefer to use interpolation, you can. This is possible by using `${}` within your template.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`JavaScript output: transformed source code 1`] = `
4+
"module.exports = (
5+
<menu icon=<img />>
6+
<button />
7+
</menu>
8+
);
9+
"
10+
`;
11+
12+
exports[`html output: generated html 1`] = `
13+
<menu
14+
icon={<img />}
15+
>
16+
<button />
17+
</menu>
18+
`;
19+
20+
exports[`static html output: static html 1`] = `"<menu icon=\\"[object Object]\\"><button></button></menu>"`;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = pug`
2+
menu
3+
button
4+
block icon
5+
img
6+
`;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import testHelper from './test-helper';
2+
3+
testHelper(__dirname + '/block-attribute.input.js');

src/visitors/NamedBlock.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @flow
2+
3+
import type Context from '../context';
4+
import {visitJsxExpressions} from '../visitors';
5+
import {buildJSXFragment} from '../utils/jsx';
6+
7+
const NamedBlockVisitor = {
8+
jsx(node: Object, context: Context): JSXValue {
9+
const nodes = visitJsxExpressions(node.nodes, context);
10+
node.nodes = nodes.length === 1 ? nodes : [buildJSXFragment(nodes)];
11+
return node;
12+
},
13+
};
14+
15+
export default NamedBlockVisitor;

src/visitors/Tag.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,24 @@ function getAttributesAndChildren(
135135
attrs: Array<JSXAttribute | JSXSpreadAttribute>,
136136
children: Array<JSXValue>,
137137
} {
138-
const children = getChildren(node, context);
138+
let children = getChildren(node, context);
139139

140140
if (node.attributeBlocks.length) {
141141
throw new Error('Attribute blocks are not yet supported in react-pug');
142142
}
143143

144144
const attrs = getAttributes(node, context);
145+
146+
const blocks = children.filter(({type}) => type === 'NamedBlock');
147+
if (blocks.length) {
148+
children = children.filter(({type}) => type !== 'NamedBlock');
149+
attrs.push(
150+
...blocks.map(block =>
151+
t.jSXAttribute(t.jSXIdentifier(block.name), block.nodes[0]),
152+
),
153+
);
154+
}
155+
145156
context.key.handleAttributes(attrs);
146157

147158
return {attrs, children};

0 commit comments

Comments
 (0)