1

I try to create an own component in Angular 19 that works similar to the MatCard. There, I can define a template like:

    <mat-card appearance="outlined">
        <mat-card-header>
            <h3>It's a kind of header</h3>
        </mat-card-header>

        <mat-card-content>
            Yippie, here comes my content.
        </mat-card-content>

        <mat-card-actions>
            act as you want
        </mat-card-actions>
    </mat-card>

What is this kind of template called so I can look for some examples?

1

1 Answer 1

2

The technique you're looking for is called content projection. Essentially, you define a component per section that you need, then you define a wrapper component that renders these sections at the right places:

// the header section
@Component({
  selector: 'app-card-header',
  standalone: true,
  imports: [CommonModule],
  // note that it's possible to wrap this too, as it's a normal Angular component
  // we're just rendering whatever was passed into the component, to keep it simple
  template: '<ng-content />',
})
export class CardHeaderComponent {}

// the content section
@Component({
  selector: 'app-card-content',
  standalone: true,
  imports: [CommonModule],
  template: '<ng-content />',
})
export class CardContentComponent {}

// the footer section
@Component({
  selector: 'app-card-footer',
  standalone: true,
  imports: [CommonModule],
  template: '<ng-content />',
})
export class CardFooterComponent {}

// the wrapper component
@Component({
  selector: 'app-card',
  standalone: true,
  imports: [CommonModule],
  template: `
    <!-- this means: if there was an <app-card-header> passed to the component, render it here -->
    <ng-content select="app-card-header"></ng-content>
    <ng-content select="app-card-content"></ng-content>
    <ng-content select="app-card-footer"></ng-content>`
})
export class CardComponent {}

// this is how we use it
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, CardComponent, CardHeaderComponent, CardContentComponent, CardFooterComponent],
  template: `
    <app-card>
      <app-card-header>
        <h3>It's a kind of header</h3>
      </app-card-header>

      <app-card-content>
        Yippie, here comes my content.
      </app-card-content>

      <app-card-footer>
        <button>Act as you want</button>
      </app-card-footer>
    </app-card>`,
})
export class App {}

Demo

1
  • 1
    Thanks to all your answers and the example you provided. It helped a lot.
    – parascus
    Commented Jan 30 at 21:05

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.