2

The title is not really a question it is more like an idea, I don't know what approach is best for my situation.

So, the problem. I have some 3rd party component that have some complex structure and styling. Some part of it has some predefined CSS class that I can override with CSS in my surrounding component. Something like this:

my component:

<div class="my-cmp-container">
    <some-3rd-party-cmp></some-3rd-party-cmp>
</div>

3rd party component:

<div class="3rd-party-css-class">
    ...
</div>

For example, 3rd-party-css-class has style background-color: #f00, I can override it with .my-cmp-container .3rd-party-css-class { background-color: #fff; } etc. But. What if I need to set color dynamically, it's stored in a DB for example and I can't predefine each case in my class' CSS. I just have the color in hex.

In theory I can generate unique string to set as CSS class for every instance of some-3rd-party-cmp and somehow generate CSS in my component? I'm lost a little, what is the best approach for this?

Edit: Code sample to illustrate the situation https://stackblitz.com/edit/angular-kxdatq

4
  • The 3rd party component doesn't make styling properties available for data binding? Commented Apr 19, 2019 at 17:07
  • Check [ngClass] and [ngStyle] Commented Apr 19, 2019 at 17:27
  • @ConnorsFan of course not otherwise there would be no question. :) Commented Apr 19, 2019 at 20:15
  • I added code sample on stackblitz to illustrate the situation Commented Apr 19, 2019 at 20:17

2 Answers 2

1

What you are trying to do is the subject of this open issue about stylesheet binding in Angular. Until that feature is available, you can get what you want with a custom directive. Here is a directive that retrieves the checkbox element generated by ng-zorro-antd and applies two color attributes to it. The two colors are @Input properties and the directive implements OnChanges which allows to react to property binding changes.

@Directive({
  selector: "[nz-checkbox][nz-chk-style]"
})
export class CheckBoxStyleDirective implements OnInit, OnChanges {

  @Input("nz-chk-bkgnd") chkBkgndColor: string;
  @Input("nz-chk-border") chkBorderColor: string;

  private checkbox: HTMLElement;

  constructor(private renderer: Renderer2, private el: ElementRef) { }

  ngOnInit() {
    this.checkbox = this.el.nativeElement.querySelector(".ant-checkbox-inner");
    this.updateBackgroundColor();
    this.updateBorderColor();
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes.chkBkgndColor) {
      this.updateBackgroundColor();
    }
    if (changes.chkBorderColor) {
      this.updateBorderColor();
    }
  }

  updateBackgroundColor() {
    if (this.checkbox) {
      this.renderer.setStyle(this.checkbox, "background-color", this.chkBkgndColor);
    }
  }

  updateBorderColor() {
    if (this.checkbox) {
      this.renderer.setStyle(this.checkbox, "border-color", this.chkBorderColor);
    }
  }
}

Once the directive attribute selector nz-chk-style is applied to the 3rd party element, you can set the checkbox background and border colors with property binding as follows:

<span nz-checkbox nz-chk-style [nz-chk-bkgnd]="bkgndColor" [nz-chk-border]="borderColor" >

See this interactive stackblitz for a demo.

Sign up to request clarification or add additional context in comments.

1 Comment

Not the same behavior as of original checkbox but I've got the idea. Thank you, this is much better then changing css properties.
0

Not sure if you are using Angular but you tagged it, so I guess you are.

If you want to change only the color and nothing more, instead of having a .3rd-party-css-class class, you could just have your with an ng-style like so:

<some-3rd-party-cmp ng-style="{ color: your_color_hex_variable }"></some-3rd-party-cmp>

You can also define a whole object if styles and pass it.

You can also use ng-class and pass one or an array of class names what you want to put additionally on your component:

<some-3rd-party-cmp ng-class="[cls1, cls2, cls3]"></some-3rd-party-cmp>

<some-3rd-party-cmp ng-class="[3rd-party-css-class, someCondition ? 'another-class-name' : '']"></some-3rd-party-cmp>

In the classes you can define the css rules you want to apply and thats it.

With this solutions you can avoid having extra wrapper elements for styling purposes which is a nice thing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.