Picci
Picci

Reputation: 17762

Angular2 components style driven by container defined CSS

Let's say I have a component MyComponent whose view contains a table

        <table>
            <thead>
                <tr>
                    <th class="col1">COL1</th>
                    <th class="col2">COL2</th>
                    <th class="col3">COL3</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="#item of items">
                    <td class="col1">{{item.content1}}</td>
                    <td class="col2">{{item.content2}}</td>
                    <td class="col3">{{item.content3}}</td>
                </tr>
            </tbody>
        </table>

I would like to MyComponent within different container (e.g. Container1 and Container2) and be able to define some attributes of the table (e.g. the width of each column) using the CSS files I can attach to the containers. For instance in Container1 I could define a CSS file like this

.col1 {
    width: 40%;
}
.col2 {
    width: 30%;
}
.col3 {
    width: 30%;
}

while in Container2 I could have a different CSS file with different attributes. Is this possible? Thanks

Upvotes: 1

Views: 422

Answers (3)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657348

I suggest to first go with @Abdulrahman's approach and if you run into situations where you need more flexibility because you don't know in advance what should be able to be styled from the outside, you can use shadow-piercing CSS combinator >>>:

@Component({
  selector: 'container1-cmp',
  directives: [MyComponent],
  template: `
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>`,
  styles: [`
    my-component >>> .col1 { width: 40%; }
    my-component >>> .col2 { width: 30%; }
    my-component >>> .col3 { width: 30%; }
  `]
})
export class Container1Cmp {
}
@Component({
  selector: 'container2-cmp',
  directives: [MyComponent],
  template: `
    <my-component></my-component>
    <my-component></my-component>
    <my-component></my-component>`,
  styles: [`
    my-component >>> .col1 { width: 10%; }
    my-component >>> .col2 { width: 10%; }
    my-component >>> .col3 { width: 50%; }
  `]
})
export class Container2Cmp {
}

Upvotes: 1

micronyks
micronyks

Reputation: 55443

If you have different .css files, you could leverage styleUrls in @Component decorator which can accept array of string. Please note that you can achieve your goal many ways and it has a broad scope so its hard to say particular way. But I feel like this can help you (don't know up to which extend). In plunker I'm using different stylesheets with different attributes as you said. Your question can have many answers.

http://plnkr.co/edit/RaJgtc?p=preview

@Component({
  ...
  styleUrls: ['src/style.css','src/styleone.css'],
  ...
})

Upvotes: 1

Abdulrahman Alsoghayer
Abdulrahman Alsoghayer

Reputation: 16540

You could leverage ngStyle and Input for example:

MyComponent would be:

@Component({
  selector:'table-component',
  template:`
    <table>
      <thead>
        <tr>
          <th [ngStyle]="col1css">COL1</th>
          <th [ngStyle]="col2css">COL2</th>
          <th [ngStyle]="col3css">COL3</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="#item of items">
          <td [ngStyle]="col1css">{{item.content1}}</td>
          <td [ngStyle]="col2css">{{item.content2}}</td>
          <td [ngStyle]="col3css">{{item.content3}}</td>
        </tr>
      </tbody>
  </table>`
})
export class MyComponent{
  @Input() col1Css;
  @Input() col2Css;
  @Input() col3Css;
}

And then in the containers:

@Component({
    selector: 'container1',
    directives:[MyComponent],
    template: `<table-component [col2Css]="col2Css" [col3Css]="col3Css" [col1Css]="col1Css"></table-component>`
})
export class Container1 {
  col1Css = {'width':'40%'};
  col2Css = {'width':'30%'};
  col3Css = {'width':'30%'};
}

Example in a plunker

Upvotes: 1

Related Questions