Skip to content

Commit 248076d

Browse files
committed
Handle class names in native transform
1 parent 2281c62 commit 248076d

4 files changed

Lines changed: 146 additions & 76 deletions

File tree

lib/__tests__/__snapshots__/transform.js.snap

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,62 @@ foo
269269
=========="
270270
`;
271271
272+
exports[`native components handles \`classNameBindings\` correctly 1`] = `
273+
"==========
274+
275+
import { classNameBindings } from '@ember-decorators/component';
276+
277+
@classNameBindings('a:b', 'x:y:z', 'foo::bar')
278+
export default class FooComponent extends Component {
279+
}
280+
281+
~~~~~~~~~~
282+
foo
283+
~~~~~~~~~~
284+
=> tagName: div
285+
~~~~~~~~~~
286+
287+
import { tagName } from '@ember-decorators/component';
288+
289+
@tagName(\\"\\")
290+
export default class FooComponent extends Component {
291+
}
292+
293+
~~~~~~~~~~
294+
<div class=\\"{{if this.a \\"b\\"}} {{if this.x \\"y\\" \\"z\\"}} {{unless this.foo \\"bar\\"}}\\" ...attributes>
295+
foo
296+
</div>
297+
=========="
298+
`;
299+
300+
exports[`native components handles \`classNames\` correctly 1`] = `
301+
"==========
302+
303+
import { classNames } from '@ember-decorators/component';
304+
305+
@classNames('foo', 'bar:baz')
306+
export default class FooComponent extends Component {
307+
}
308+
309+
~~~~~~~~~~
310+
foo
311+
~~~~~~~~~~
312+
=> tagName: div
313+
~~~~~~~~~~
314+
315+
import { tagName } from '@ember-decorators/component';
316+
317+
@tagName(\\"\\")
318+
export default class FooComponent extends Component {
319+
}
320+
321+
~~~~~~~~~~
322+
<div class=\\"foo bar:baz\\" ...attributes>
323+
foo
324+
</div>
325+
=========="
326+
`;
327+
272328
exports[`native components handles \`elementId\` correctly 1`] = `
273329
"==========
274330
@@ -293,6 +349,34 @@ foo
293349
=========="
294350
`;
295351
352+
exports[`native components handles single \`classNames\` item correctly 1`] = `
353+
"==========
354+
355+
import { classNames } from '@ember-decorators/component';
356+
357+
@classNames('foo')
358+
export default class FooComponent extends Component {
359+
}
360+
361+
~~~~~~~~~~
362+
foo
363+
~~~~~~~~~~
364+
=> tagName: div
365+
~~~~~~~~~~
366+
367+
import { tagName } from '@ember-decorators/component';
368+
369+
@tagName(\\"\\")
370+
export default class FooComponent extends Component {
371+
}
372+
373+
~~~~~~~~~~
374+
<div class=\\"foo\\" ...attributes>
375+
foo
376+
</div>
377+
=========="
378+
`;
379+
296380
exports[`native components replaces existing \`tagName\` 1`] = `
297381
"==========
298382

lib/__tests__/transform.js

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -271,63 +271,48 @@ describe('native components', function() {
271271
expect(generateSnapshot(source, template)).toMatchSnapshot();
272272
});
273273

274+
test('handles `classNames` correctly', () => {
275+
let source = `
276+
import { classNames } from '@ember-decorators/component';
277+
278+
@classNames('foo', 'bar:baz')
279+
export default class FooComponent extends Component {
280+
}
281+
`;
282+
283+
let template = `foo`;
284+
285+
expect(generateSnapshot(source, template)).toMatchSnapshot();
286+
});
287+
288+
test('handles single `classNames` item correctly', () => {
289+
let source = `
290+
import { classNames } from '@ember-decorators/component';
291+
292+
@classNames('foo')
293+
export default class FooComponent extends Component {
294+
}
295+
`;
296+
297+
let template = `foo`;
298+
299+
expect(generateSnapshot(source, template)).toMatchSnapshot();
300+
});
301+
302+
test('handles `classNameBindings` correctly', () => {
303+
let source = `
304+
import { classNameBindings } from '@ember-decorators/component';
305+
306+
@classNameBindings('a:b', 'x:y:z', 'foo::bar')
307+
export default class FooComponent extends Component {
308+
}
309+
`;
310+
311+
let template = `foo`;
312+
313+
expect(generateSnapshot(source, template)).toMatchSnapshot();
314+
});
274315
//
275-
// test('handles `classNames` correctly', () => {
276-
// let source = `
277-
// export default Component.extend({
278-
// classNames: ['foo', 'bar:baz'],
279-
// });
280-
// `;
281-
//
282-
// let template = `foo`;
283-
//
284-
// expect(generateSnapshot(source, template)).toMatchSnapshot();
285-
// });
286-
//
287-
// test('handles single `classNames` item correctly', () => {
288-
// let source = `
289-
// export default Component.extend({
290-
// classNames: ['foo'],
291-
// });
292-
// `;
293-
//
294-
// let template = `foo`;
295-
//
296-
// expect(generateSnapshot(source, template)).toMatchSnapshot();
297-
// });
298-
//
299-
// test('handles `classNameBindings` correctly', () => {
300-
// let source = `
301-
// export default Component.extend({
302-
// classNameBindings: ['a:b', 'x:y:z', 'foo::bar'],
303-
// });
304-
// `;
305-
//
306-
// let template = `foo`;
307-
//
308-
// expect(generateSnapshot(source, template)).toMatchSnapshot();
309-
// });
310-
//
311-
// test('throws if `Component.extend({ ... })` is not found', () => {
312-
// let source = `
313-
// export default class extends Component {
314-
// }
315-
// `;
316-
//
317-
// expect(() => transform(source, '')).toThrowErrorMatchingInlineSnapshot(
318-
// `"Unsupported component type. Only classic components (\`Component.extend({ ... }\`) are supported currently."`
319-
// );
320-
// });
321-
//
322-
// test('throws if `Component.extend({ ... })` argument is not found', () => {
323-
// let source = `
324-
// export default Component.extend();
325-
// `;
326-
//
327-
// expect(() => transform(source, '')).toThrowErrorMatchingInlineSnapshot(
328-
// `"Could not find object argument in \`export default Component.extend({ ... });\`"`
329-
// );
330-
// });
331316
//
332317
// test('skips tagless components', () => {
333318
// let source = `

lib/transform/native.js

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
findClassNameBindings,
1313
findAttributeBindings,
1414
isMethod,
15+
removeDecorator,
1516
ensureImport,
1617
removeImport,
1718
isProperty,
@@ -118,13 +119,11 @@ module.exports = function transformNativeComponent(root, options) {
118119
let attributeBindings = findAttributeBindings(classDeclaration);
119120
debug('attributeBindings: %o', attributeBindings);
120121

121-
/*
122-
let classNames = findClassNames(properties);
122+
let classNames = findClassNames(classDeclaration);
123123
debug('classNames: %o', classNames);
124124

125-
let classNameBindings = findClassNameBindings(properties);
125+
let classNameBindings = findClassNameBindings(classDeclaration);
126126
debug('classNameBindings: %o', classNameBindings);
127-
*/
128127

129128
// set `@tagName('')`
130129
addClassDecorator(exportDefaultDeclaration, 'tagName', [j.stringLiteral('')]);
@@ -146,17 +145,12 @@ module.exports = function transformNativeComponent(root, options) {
146145
// .filter(path => path.parentPath === properties)
147146
.filter(
148147
path => isProperty(path, 'elementId')
149-
// isProperty(path, 'attributeBindings') ||
150-
// isProperty(path, 'classNames') ||
151-
// isProperty(path, 'classNameBindings')
152148
)
153149
.remove();
154150

155-
let attributeBindingsDecorator = findDecorator(classDeclaration, 'attributeBindings');
156-
if (attributeBindingsDecorator) {
157-
j(attributeBindingsDecorator).remove();
158-
removeImport(root, 'attributeBindings', '@ember-decorators/component');
159-
}
151+
removeDecorator(root, classDeclaration, 'attributeBindings', '@ember-decorators/component');
152+
removeDecorator(root, classDeclaration, 'classNames', '@ember-decorators/component');
153+
removeDecorator(root, classDeclaration, 'classNameBindings', '@ember-decorators/component');
160154

161155
let newSource = root.toSource();
162156

@@ -165,7 +159,7 @@ module.exports = function transformNativeComponent(root, options) {
165159
if (options.hasComponentCSS) {
166160
classNodes.push(b.mustache('styleNamespace'));
167161
}
168-
/*
162+
169163
for (let className of classNames) {
170164
classNodes.push(b.text(className));
171165
}
@@ -176,7 +170,6 @@ module.exports = function transformNativeComponent(root, options) {
176170
classNodes.push(b.mustache(`if this.${property} "${truthy}"${falsy ? ` "${falsy}"` : ''}`));
177171
}
178172
});
179-
*/
180173

181174
let attrs = [];
182175

@@ -187,7 +180,7 @@ module.exports = function transformNativeComponent(root, options) {
187180
attributeBindings.forEach((value, key) => {
188181
attrs.push(b.attr(key, b.mustache(`this.${value}`)));
189182
});
190-
/*
183+
191184
if (classNodes.length === 1) {
192185
attrs.push(b.attr('class', classNodes[0]));
193186
} else if (classNodes.length !== 0) {
@@ -200,7 +193,6 @@ module.exports = function transformNativeComponent(root, options) {
200193
attrs.push(b.attr('class', b.concat(parts)));
201194
}
202195

203-
*/
204196
attrs.push(b.attr('...attributes', b.text('')));
205197

206198
return { newSource, attrs, tagName };

lib/utils/native.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ function findAttributeBindings(classDeclaration) {
129129
return attrBindings;
130130
}
131131

132-
function findClassNames(properties) {
133-
return findStringArrayProperties(properties, 'classNames');
132+
function findClassNames(classDeclaration) {
133+
return findStringArrayDecorator(classDeclaration, 'classNames');
134134
}
135135

136-
function findClassNameBindings(properties) {
136+
function findClassNameBindings(classDeclaration) {
137137
let classNameBindings = new Map();
138-
for (let binding of findStringArrayProperties(properties, 'classNameBindings')) {
138+
for (let binding of findStringArrayDecorator(classDeclaration, 'classNameBindings')) {
139139
let parts = binding.split(':');
140140

141141
if (parts.length === 1) {
@@ -152,6 +152,14 @@ function findClassNameBindings(properties) {
152152
return classNameBindings;
153153
}
154154

155+
function removeDecorator(root, classDeclaration, name, source) {
156+
let decorator = findDecorator(classDeclaration, name);
157+
if (decorator) {
158+
j(decorator).remove();
159+
removeImport(root, name, source);
160+
}
161+
}
162+
155163
function indentLines(content) {
156164
return content
157165
.split('\n')
@@ -251,6 +259,7 @@ module.exports = {
251259
findElementId,
252260
findTagName,
253261
findDecorator,
262+
removeDecorator,
254263
ensureImport,
255264
removeImport,
256265
indentLines,

0 commit comments

Comments
 (0)