Skip to content
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

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

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
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.
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
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
…4854)

Updates the template AST to capture the content of `ng-content` elements instead of throwing an error.

PR Close angular#54854
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
…ngular#54854)

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

PR Close angular#54854
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
…o template type checker (angular#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 angular#54854
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
…4854)

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.

PR Close angular#54854
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
angular#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 angular#54854
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
… content (angular#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 angular#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