Skip to content

feat(core): add support for fallback content in ng-content #54854

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from

Conversation

crisbeto
Copy link
Member

Adds the ability to specify content that Angular should fall back to if nothing is projected into an ng-content slot. For example, if we have the following setup

@Component({
  selector: 'my-comp',
  template: `
    <ng-content select="header">Default header</ng-content>
    <ng-content select="footer">Default footer</ng-content>
  `
})
class MyComp {}

@Component({
  template: `
    <my-comp>
      <footer>New footer</footer>
    </my-comp>
  `
})
class MyApp {}

The instance of my-comp in the app will have the default header and the new footer.

Note: Angular's content projection happens during creation time. This means that dynamically changing the contents of the slot will not cause the default content to show up, e.g. if a if block goes from true to false.

Fixes #12530.

@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer area: core Issues related to the framework runtime target: major This PR is targeted for the next major release labels Mar 14, 2024
@ngbot ngbot bot added this to the Backlog milestone Mar 14, 2024
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Mar 14, 2024
@crisbeto crisbeto marked this pull request as ready for review March 14, 2024 08:51
@pullapprove pullapprove bot requested a review from atscott March 14, 2024 08:51
@crisbeto crisbeto modified the milestones: Backlog, v18-candidates Mar 14, 2024
@crisbeto crisbeto force-pushed the ng-content-fallback branch from 692a1f8 to 2448101 Compare March 14, 2024 20:19
Copy link
Member

@pkozlowski-opensource pkozlowski-opensource left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, thank you for adding very thorough tests. The only addition I could think of are tests for re-projection with the default content.

Updates the template AST to capture the content of `ng-content` elements instead of throwing an error.
Updates the code that generates the `projection` instruction to pass the template function containing the default content into it.
…o template type checker

Adds logic to ingest the content of an `ng-content` element in the template type checker. We treat `ng-content` as a `ScopedNode`, because its content is inserted conditionally.
Adds the ability to specify content that Angular should fall back to if nothing is projected into an `ng-content` slot. For example, if we have the following setup

```
@component({
  selector: 'my-comp',
  template: `
    <ng-content select="header">Default header</ng-content>
    <ng-content select="footer">Default footer</ng-content>
  `
})
class MyComp {}

@component({
  template: `
    <my-comp>
      <footer>New footer</footer>
    </my-comp>
  `
})
class MyApp {}
```

The instance of `my-comp` in the app will have the default header and the new footer.

**Note:** Angular's content projection happens during creation time. This means that dynamically changing the contents of the slot will not cause the default content to show up, e.g. if a `if` block goes from `true` to `false`.

Fixes angular#12530.
Moves the logic that declares a template out into a separate function so that it can be reused in other places like control flow and defer, without having to call directly into the `template` instruction.
… content

Passes the attributes of the `ng-content` element to the container that is created for the fallback content so that it can be re-projected into the same slot.
@crisbeto crisbeto force-pushed the ng-content-fallback branch from 2448101 to 623a491 Compare March 25, 2024 14:13
Copy link
Contributor

@atscott atscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: language-service

@crisbeto crisbeto added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Mar 25, 2024
@dylhunn
Copy link
Contributor

dylhunn commented Mar 26, 2024

This PR was merged into the repository by commit 2fc11ea.

@dylhunn dylhunn closed this in c734808 Mar 26, 2024
dylhunn pushed a commit that referenced this pull request Mar 26, 2024
…54854)

Updates the code that generates the `projection` instruction to pass the template function containing the default content into it.

PR Close #54854
dylhunn pushed a commit that referenced this pull request Mar 26, 2024
…o template type checker (#54854)

Adds logic to ingest the content of an `ng-content` element in the template type checker. We treat `ng-content` as a `ScopedNode`, because its content is inserted conditionally.

PR Close #54854
dylhunn pushed a commit that referenced this pull request Mar 26, 2024
Adds the ability to specify content that Angular should fall back to if nothing is projected into an `ng-content` slot. For example, if we have the following setup

```
@component({
  selector: 'my-comp',
  template: `
    <ng-content select="header">Default header</ng-content>
    <ng-content select="footer">Default footer</ng-content>
  `
})
class MyComp {}

@component({
  template: `
    <my-comp>
      <footer>New footer</footer>
    </my-comp>
  `
})
class MyApp {}
```

The instance of `my-comp` in the app will have the default header and the new footer.

**Note:** Angular's content projection happens during creation time. This means that dynamically changing the contents of the slot will not cause the default content to show up, e.g. if a `if` block goes from `true` to `false`.

Fixes #12530.

PR Close #54854
dylhunn pushed a commit that referenced this pull request Mar 26, 2024
#54854)

Moves the logic that declares a template out into a separate function so that it can be reused in other places like control flow and defer, without having to call directly into the `template` instruction.

PR Close #54854
dylhunn pushed a commit that referenced this pull request Mar 26, 2024
… content (#54854)

Passes the attributes of the `ng-content` element to the container that is created for the fallback content so that it can be re-projected into the same slot.

PR Close #54854
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Apr 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ng-content default content
4 participants