Skip to content

Commit 703a3fa

Browse files
committed
Handle class names in native transform
1 parent 7a57743 commit 703a3fa

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
@@ -293,6 +293,62 @@ foo
293293
=========="
294294
`;
295295
296+
exports[`native components handles \`classNameBindings\` correctly 1`] = `
297+
"==========
298+
299+
import { classNameBindings } from '@ember-decorators/component';
300+
301+
@classNameBindings('a:b', 'x:y:z', 'foo::bar')
302+
export default class FooComponent extends Component {
303+
}
304+
305+
~~~~~~~~~~
306+
foo
307+
~~~~~~~~~~
308+
=> tagName: div
309+
~~~~~~~~~~
310+
311+
import { tagName } from '@ember-decorators/component';
312+
313+
@tagName(\\"\\")
314+
export default class FooComponent extends Component {
315+
}
316+
317+
~~~~~~~~~~
318+
<div class=\\"{{if this.a \\"b\\"}} {{if this.x \\"y\\" \\"z\\"}} {{unless this.foo \\"bar\\"}}\\" ...attributes>
319+
foo
320+
</div>
321+
=========="
322+
`;
323+
324+
exports[`native components handles \`classNames\` correctly 1`] = `
325+
"==========
326+
327+
import { classNames } from '@ember-decorators/component';
328+
329+
@classNames('foo', 'bar:baz')
330+
export default class FooComponent extends Component {
331+
}
332+
333+
~~~~~~~~~~
334+
foo
335+
~~~~~~~~~~
336+
=> tagName: div
337+
~~~~~~~~~~
338+
339+
import { tagName } from '@ember-decorators/component';
340+
341+
@tagName(\\"\\")
342+
export default class FooComponent extends Component {
343+
}
344+
345+
~~~~~~~~~~
346+
<div class=\\"foo bar:baz\\" ...attributes>
347+
foo
348+
</div>
349+
=========="
350+
`;
351+
296352
exports[`native components handles \`elementId\` correctly 1`] = `
297353
"==========
298354
@@ -317,6 +373,34 @@ foo
317373
=========="
318374
`;
319375
376+
exports[`native components handles single \`classNames\` item correctly 1`] = `
377+
"==========
378+
379+
import { classNames } from '@ember-decorators/component';
380+
381+
@classNames('foo')
382+
export default class FooComponent extends Component {
383+
}
384+
385+
~~~~~~~~~~
386+
foo
387+
~~~~~~~~~~
388+
=> tagName: div
389+
~~~~~~~~~~
390+
391+
import { tagName } from '@ember-decorators/component';
392+
393+
@tagName(\\"\\")
394+
export default class FooComponent extends Component {
395+
}
396+
397+
~~~~~~~~~~
398+
<div class=\\"foo\\" ...attributes>
399+
foo
400+
</div>
401+
=========="
402+
`;
403+
320404
exports[`native components replaces existing \`tagName\` 1`] = `
321405
"==========
322406

lib/__tests__/transform.js

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

311+
test('handles `classNames` correctly', () => {
312+
let source = `
313+
import { classNames } from '@ember-decorators/component';
314+
315+
@classNames('foo', 'bar:baz')
316+
export default class FooComponent extends Component {
317+
}
318+
`;
319+
320+
let template = `foo`;
321+
322+
expect(generateSnapshot(source, template)).toMatchSnapshot();
323+
});
324+
325+
test('handles single `classNames` item correctly', () => {
326+
let source = `
327+
import { classNames } from '@ember-decorators/component';
328+
329+
@classNames('foo')
330+
export default class FooComponent extends Component {
331+
}
332+
`;
333+
334+
let template = `foo`;
335+
336+
expect(generateSnapshot(source, template)).toMatchSnapshot();
337+
});
338+
339+
test('handles `classNameBindings` correctly', () => {
340+
let source = `
341+
import { classNameBindings } from '@ember-decorators/component';
342+
343+
@classNameBindings('a:b', 'x:y:z', 'foo::bar')
344+
export default class FooComponent extends Component {
345+
}
346+
`;
347+
348+
let template = `foo`;
349+
350+
expect(generateSnapshot(source, template)).toMatchSnapshot();
351+
});
311352
//
312-
// test('handles `classNames` correctly', () => {
313-
// let source = `
314-
// export default Component.extend({
315-
// classNames: ['foo', 'bar:baz'],
316-
// });
317-
// `;
318-
//
319-
// let template = `foo`;
320-
//
321-
// expect(generateSnapshot(source, template)).toMatchSnapshot();
322-
// });
323-
//
324-
// test('handles single `classNames` item correctly', () => {
325-
// let source = `
326-
// export default Component.extend({
327-
// classNames: ['foo'],
328-
// });
329-
// `;
330-
//
331-
// let template = `foo`;
332-
//
333-
// expect(generateSnapshot(source, template)).toMatchSnapshot();
334-
// });
335-
//
336-
// test('handles `classNameBindings` correctly', () => {
337-
// let source = `
338-
// export default Component.extend({
339-
// classNameBindings: ['a:b', 'x:y:z', 'foo::bar'],
340-
// });
341-
// `;
342-
//
343-
// let template = `foo`;
344-
//
345-
// expect(generateSnapshot(source, template)).toMatchSnapshot();
346-
// });
347-
//
348-
// test('throws if `Component.extend({ ... })` is not found', () => {
349-
// let source = `
350-
// export default class extends Component {
351-
// }
352-
// `;
353-
//
354-
// expect(() => transform(source, '')).toThrowErrorMatchingInlineSnapshot(
355-
// `"Unsupported component type. Only classic components (\`Component.extend({ ... }\`) are supported currently."`
356-
// );
357-
// });
358-
//
359-
// test('throws if `Component.extend({ ... })` argument is not found', () => {
360-
// let source = `
361-
// export default Component.extend();
362-
// `;
363-
//
364-
// expect(() => transform(source, '')).toThrowErrorMatchingInlineSnapshot(
365-
// `"Could not find object argument in \`export default Component.extend({ ... });\`"`
366-
// );
367-
// });
368353
//
369354
// test('skips tagless components', () => {
370355
// 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)