Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply CSS classes to another component in AngularDart?

Let's say there is a simple framework to display popups:

@Component(
  selector: 'popup-host',
  template: '''
      <div class="popup-container">
        <ng-template #popupRef></ng-template>
      </div>
  ''',
  styles: ['.popup-container { position: absolute; top: 100; left: 100; z-index: 100; }'],
)
class PopupContainerComponent {
  final PopupController _controller;
  final ComponentLoader _loader;

  PopupContainerComponent(this._controller, this._loader);

  void ngOnInit() {
    _controller.container = this;
  }

  @ViewChild('popupRef', read: ComponentRef)
  ComponentRef popupRef;

  void render(PopupConfig config) {
    final componentRef = _loader.loadNextTo(config.factory, popupRef);
    if (componentRef.instance is HasValueSetter) {
      componentRef.instance.value = config.value;
    }
  }
}

@Injectable()
class PopupController {
  PopupContainerComponent _container;
  set container(PopupContainerComponent container) => _container = container;

  void showPopup(PopupConfig config) {
    container.render(config);
  }
  ...
}

class PopupConfig {
  final ComponentFactory factory;
  final dynamic value;
  PopupConfig(this.factory, [this.value]);
}

abstract class HasValueSetter {
  set value(dynamic value);
}

This can then be used like this:

// Somewhere in the root template
<popup-host></popup-host>

// In popup.dart
@Component(
  selector: 'happy-popup',
  template: '''
      <div class="header">This is the popup content.</div>
      <div class="main">The value is {{value}}.</div>
      <div class="footer">I am happy!</div>
  ''',
)
class HappyPopupComponent implements HasValueSetter {
  @override
  dynamic value;
}

// In some_other.dart
@Component(
  ...
  styles: [
    '.header { font-weight: bold }',
    '.main { color: red }',
    '.footer { color: green; font-style: italic }',
  ],
  ...
)
class SomeOtherComponent {
  final PopupController _popupController;
  ...
  SomeOtherComponent(this._popupController, ...) ...;

  void displayPopup() {
    _popupController.showPopup(HappyPopupComponentNgFactory, 42);
  }
}
...

Is there a way to forward styles from <some-other-component> to <happy-popup> without having to define them at the root of the app?

like image 947
Sergiy Belozorov Avatar asked Nov 29 '19 20:11

Sergiy Belozorov


People also ask

How we can add style to the particular component in Angular?

There are several ways to add styles to a component: By setting styles or styleUrls metadata. Inline in the template HTML. With CSS imports.

How do you implement a class in CSS?

To select elements with a specific class, write a period (.) character, followed by the name of the class. You can also specify that only specific HTML elements should be affected by a class. To do this, start with the element name, then write the period (.)


Video Answer


2 Answers

You could achieve this by splitting your components code into separate files - or separate CSS file in your case.

Instead of writing the style straight in the component's - styles, you would import the CSS file by using the styleUrls. That way you can pass a file(s) with your styles, and the file can be shared amongst multiple components.

@Component(
      styleUrls: ['./hero1.css', './folder/hero2.css'],
)

Bear in mind that the URLs in styleUrls are relative to the component.

Another benefit of importing the css with styleUrls is that it also grants you the ability to use imports within that file.

hero1.css

@import './folder/hero2.css';

FYI: It's a common practice to split your components code into separate files.

  • hero.dart
  • hero.css
  • hero.html

And then in your dart file reference them as:

@Component(
      templateUrl: './hero.html',
      styleUrls: ['./hero.css'],
)

Please refer to AngularDart - Component Styles for brief information about this.

like image 180
Dino Avatar answered Oct 13 '22 01:10

Dino


As your popup isn't a child of the component that opened it you cannot use ::ng-deep

the only thing I think that will work is to remove view encapsulation from the host, the popup and the component that opens the popup (try only the popup and component that opens the popup first, if that doesn't work, remove the host's encapsulation as well.)

@Component(
  selector: 'happy-popup',
  template: '''
      <div class="header">This is the popup content.</div>
      <div class="main">The value is {{value}}.</div>
      <div class="footer">I am happy!</div>
  ''',
  encapsulation: ViewEncapsulation.None // <=== no encapsulation at all
)
class HappyPopupComponent implements HasValueSetter {
like image 24
Ron Avatar answered Oct 13 '22 00:10

Ron