Skip to content

Commit

Permalink
Handle localClassNameBindings with composed classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
dfreeman committed Sep 27, 2016
1 parent 245f2ea commit 01a877a
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 7 deletions.
36 changes: 29 additions & 7 deletions addon/mixins/component-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export default Ember.Mixin.create({
this._super();
this.classNameBindings = [
...this.classNameBindings,
...this.localClassNames.map(className => `styles.${className}`),
...this.localClassNameBindings.map(bindingSource => localClassNameBinding(this, bindingSource))
...localClassNames(this),
...localClassNameBindings(this)
];
},

Expand All @@ -26,13 +26,35 @@ export default Ember.Mixin.create({
})
});

function localClassNameBinding(component, bindingSource) {
let [property, trueClass = dasherize(property), falseClass] = bindingSource.split(':');
let binding = `${property}:${component.get(`styles.${trueClass}`)}`;
function localClassNames(component) {
return component.localClassNames.map(className => `styles.${className}`);
}

if (falseClass) {
binding += `:${component.get(`styles.${falseClass}`)}`;
function localClassNameBindings(component) {
return component.localClassNameBindings.reduce((bindings, bindingSource) => {
return bindings.concat(buildBindings(component, bindingSource));
}, []);
}

function buildBindings(component, bindingSource) {
let styles = component.get('styles');
let [property, trueStyle = dasherize(property), falseStyle] = bindingSource.split(':');

let trueClasses = (styles[trueStyle] || '').split(/\s+/);
let falseClasses = (styles[falseStyle] || '').split(/\s+/);
let bindings = [];

for (let i = 0, len = Math.max(trueClasses.length, falseClasses.length); i < len; i++) {
bindings.push(bindingString(property, trueClasses[i], falseClasses[i]));
}

return bindings;
}

function bindingString(property, trueClass = '', falseClass = '') {
let binding = `${property}:${trueClass || ''}`;
if (falseClass) {
binding += `:${falseClass}`;
}
return binding;
}
73 changes: 73 additions & 0 deletions tests/integration/mixins/component-mixin-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,76 @@ test('it honors a configured mapped localClassNameBinding with an inverse', func
assert.notOk($element.is('.bar'));
assert.ok($element.is('.baz'));
});

test('it supports localClassNames with composition', function(assert) {
let styles = {
'some-class': 'foo bar baz'
};

this.owner.register('styles:components/test-component', styles);
this.owner.register('component:test-component', Ember.Component.extend(ComponentMixin, {
classNames: 'test-component',
localClassNames: 'some-class'
}));

this.render(hbs`{{test-component}}`);

let $element = this.$('.test-component');
assert.ok($element.is('.foo'));
assert.ok($element.is('.bar'));
assert.ok($element.is('.baz'));
});

test('it supports localClassNameBindings with composition in the positive class', function(assert) {
let styles = {
'on-class': 'foo bar',
'off-class': 'baz'
};

this.set('flag', true);

this.owner.register('styles:components/test-component', styles);
this.owner.register('component:test-component', Ember.Component.extend(ComponentMixin, {
classNames: 'test-component',
localClassNameBindings: 'dynamicValue:on-class:off-class'
}));

this.render(hbs`{{test-component dynamicValue=flag}}`);

let $element = this.$('.test-component');
assert.ok($element.is('.foo'));
assert.ok($element.is('.bar'));
assert.notOk($element.is('.baz'));

Ember.run(() => this.set('flag', false));
assert.notOk($element.is('.foo'));
assert.notOk($element.is('.bar'));
assert.ok($element.is('.baz'));
});

test('it supports localClassNameBindings with composition in the negative class', function(assert) {
let styles = {
'on-class': 'foo',
'off-class': 'bar baz'
};

this.set('flag', true);

this.owner.register('styles:components/test-component', styles);
this.owner.register('component:test-component', Ember.Component.extend(ComponentMixin, {
classNames: 'test-component',
localClassNameBindings: 'dynamicValue:on-class:off-class'
}));

this.render(hbs`{{test-component dynamicValue=flag}}`);

let $element = this.$('.test-component');
assert.ok($element.is('.foo'));
assert.notOk($element.is('.bar'));
assert.notOk($element.is('.baz'));

Ember.run(() => this.set('flag', false));
assert.notOk($element.is('.foo'));
assert.ok($element.is('.bar'));
assert.ok($element.is('.baz'));
});

0 comments on commit 01a877a

Please sign in to comment.