rimlin
rimlin

Reputation: 397

How to pass host component's CSS class to children?

I cannot understand how to pass host component CSS class to a children element. I created a custom element:

...

const CUSTOM_INPUT_VALUE_PROVIDER: Provider = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => FormFieldComponent),
  multi: true,
}

@Component({
  moduleId: module.id,
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [CUSTOM_INPUT_VALUE_PROVIDER],
  selector: 'form-field',
  template: `
    <div>
      <input
        (change)="onChange($event.target.value)"
        (blur)="onTouched()"
        [disabled]="innerIsDisabled"
        type="text"
        [value]="innerValue" />
    </div>
  `
})
export class FormFieldComponent implements ControlValueAccessor {
  @Input() innerValue: string;

  innerIsDisabled: boolean = false;

  onChange = (_) => {};
  onTouched = () => {};

  writeValue(value: any) {
    if (value !== this.innerValue) {
      this.value = value;
    }
  }

  registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
  registerOnTouched(fn: () => void): void { this.onTouched = fn; }

  setDisabledState(isDisabled: boolean) {
    this.innerIsDisabled = isDisabled;
  }

  get value(): any {
    return this.innerValue;
  }

  set value(value: any) {
    if (value !== this.innerValue) {
      this.innerValue = value;
      this.onChange(value);
    }
  }
}

And then use it like this in some reactive form:

<form-field formControlName="title"></form-field>

Problem: I added some validation in FormBuilder to title form control and when it not pass validation, Angular add classic css classes to form-field element: ng-pristine ng-invalid ng-touched.

How i can pass this CSS classes from host element to my input element in form-field component?


It is not duplicate of Angular 2 styling not applying to Child Component. Changing Encapsulation does not resolve the problem.

Upvotes: 2

Views: 1922

Answers (1)

Alex Willenbrink
Alex Willenbrink

Reputation: 162

I think there's a way to do what you want by just knowing the angular classes of the hosting elements and not necessarily passing them down.

If so, your work-around would look something like this in the css of the custom form element:

:host.(ng-class)>>>HTMLelement {
  property: value
}

Example:

:host.ng-valid>>>div {
  border-left: 5px solid #42a948;
}
  • The ":host" part of this allows us to use the hosting (parent) html elements
  • The ">>>" is the deep selector that allows us to apply these styles to all children matching selection property (in this case, we're looking for div elements)

Upvotes: 1

Related Questions