Kuzzy
Kuzzy

Reputation: 640

Ember 1.13, class names order in a component

I've created a simple component to render icons from SVG sprite. This component should have a default CSS class to manage it's styles globally (.svg-icon). Also, I want to have a possibility to add some context dependent styles via class names through 'class' attribute.

JS:

App.SvgIconComponent = Ember.Component.extend
   layoutName: 'components/svg-icon'
   classNames: ['svg-icon']
   tagName: 'svg'
   attributeBindings: ['width', 'height', 'fill'],

   width: 16
   height: 16
   fill: 'currentColor'

Template:

<use xlink:href="#svg-icon-{{name}}"/>

Usage:

{{svg-icon name="facebook" class="social__icon" width="14" height="14"}}

HTML output:

<svg id="ember1012" width="14" height="14" fill="currentColor" class="social__icon ember-view svg-icon">
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#svg-icon-facebook"></use>
</svg>

The problem is that Ember pushed my default class (.svg-icon) into the end of classes list. But, to avoid some issues with cascade, I need this class at the start of classes list (class="svg-icon social__icon ember-view"). Is it possible to achieve?

I know, that I can set classes names with classNameBindings property, but in this case I will need to use some attribute different from 'class'. Use of native 'class' attribute is preferable.

Thnx.

Upvotes: 0

Views: 297

Answers (1)

Ember Freak
Ember Freak

Reputation: 12872

Try this,

{{svg-icon name="facebook" classNames="social__icon" width="14" height="14"}}

The above will work but it is not using class attribute. so its not matching your requirement.

but if that does not align with your requirement, you can try setting classNames manually in init method.

init(){
    this._super(...arguments);
    console.log(' Classess ',this.get('classNames')); //You will get classNames, you can do rearrange the classNames array
    this.get('classNames').unshiftObject('svg-icon'); //to force svg-icon to be first in classNames array.    
  }

Update1

Above init() won't work. so I believe classNames values are added to last. using native class to come first is not possible AFAIK. but then for your requirement

I know, that I can set classes names with classNameBindings property, but in this case I will need to use some attribute different from 'class'

You can mention different class names for particular attribute is true.

{{my-component is_social__icon=false }}

and inside my-component.js

classNameBindings:['is_social__icon:social__icon']

Update2
1)You can also specify class names for true and false values too in classNameBindings

export default Ember.Component.extend({
  classNameBindings: ['isEnabled:enabled:disabled'],
  isEnabled: false
});

isEnabled - true - then it will include enabled class name isEnabled - false - then it will include disabled class name

2) You can even specify class name to be added only for false value.

 classNameBindings: ['isEnabled::disabled'],

3) you can specify multiple properties

 classNameBindings:['isSocialIcon':'social__icon','isActive':'selected']

you can provide values for isSocialIcon and isActive property to the component.

{{my-component isSocialIcon=true isActive=(unless social.inactive) }}

if isActive is resolved to true then it will add class social__icon selected to my-component.

Reference : https://guides.emberjs.com/v1.13.0/components/customizing-a-components-element/#toc_customizing-class-names

Upvotes: 1

Related Questions