# @coreteq/ngx-projection

> A simple content projection directive

Latest version **0.3.0** (published 2023-12-12) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install @coreteq/ngx-projection
pnpm add @coreteq/ngx-projection
yarn add @coreteq/ngx-projection
bun add @coreteq/ngx-projection
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 0.3.0 |
| Published | 2023-12-12 |
| First published | 2023-01-26 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 42.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | CORETEQ Technology |
| Maintainers | s.borodin |
| Keywords | angular, typescript, directive, component, interpolation, content-projection, utils |

## Links

- npm: https://www.npmjs.com/package/@coreteq/ngx-projection
- npm.io page: https://npm.io/package/@coreteq/ngx-projection

## Dependencies (1)

- [tslib](https://npm.io/package/tslib.md) ^2.3.0

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 0.3.0 (latest) — 2023-12-12
- 0.2.0 — 2023-04-23
- 0.1.0 — 2023-01-26

## README

[![MIT](https://img.shields.io/packagist/l/doctrine/orm.svg?style=flat-square)]()
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
[![сoreteq](https://img.shields.io/badge/@-coreteq-383636?style=flat-square&labelColor=277CCC)](https://coreteq.eu)

# 👻 Flexible way to project dynamic content

<b>✨ Ngx-projection</b> library provides <b>NgxContentOutlet</b> standalone structural directive, that allows you to project dynamic content as well as:
- [*ngTemplateOutlet](https://angular.io/api/common/NgTemplateOutlet), that creates embedded views based on the TemplateRef template
- [*ngComponentOutlet](https://angular.io/api/common/NgComponentOutlet), that creates a dynamic component based on a reference to the component class
- or a simple [{{ interpolation }}](https://angular.io/guide/interpolation) that displays a primitive value tied to a variable in the template

# Compatibility with Angular Versions

<table>
  <thead>
    <tr>
      <th>@coreteq/ngx-projection</th>
      <th>Angular</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        1.x
      </td>
      <td>
        >= 14.0.0
      </td>
    </tr>
  </tbody>
</table>

# Table of contents

- [Installation](#installation)
- [Setup](#setup)
- [Usage](#usage)
  - [Use with component class reference](#use-with-component-class-reference)
    - [Use with optional custom injector](#use-with-optional-custom-injector)
  - [Use with TemplateRef](#use-with-templateref)
    - [Use with a context object](#use-with-a-context-object)
  - [Use with primitive type value](#use-with-primitive-type-value)
- [Api](#api)

# 🚀 Installation

```bash
npm install @coreteq/ngx-projection
```

# Setup
Add standalone directive `NgxContentOutlet` to app `NgModule`
```ts
import { NgxContentOutlet } from '@coreteq/ngx-projection';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, NgxContentOutlet], // <--- you need to add NgxContentOutlet
  bootstrap: [AppComponent]
})
export class AppModule {}
```

# Usage

## Use with component class reference

Getting as input a reference to the component class, the `*ngxContentOutlet` directive dynamically instantiates the component and inserts its host view into this container.

```html
<ng-container *ngxContentOutlet="component as content">
  {{ content }}
</ng-container>
<!--- or --->
<ng-container *ngxContentOutlet="component"></ng-container>
```

```ts
import { ChildComponent } from './child.component'

export class AppComponent {
  component = ChildComponent;
}
```

### Use with optional custom injector

Optional custom injector that will be used as parent for the component. Defaults to the injector of the current view container.

```html
<ng-container *ngxContentOutlet="component as content; injector: customInjector">
  {{ content }}
</ng-container>
```

```ts
import { ChildComponent } from './child.component';
import { Injector } from "@angular/core";

export class RendererComponent {
  component = ChildComponent;
  customInjector: Injector;

  constructor(injector: Injector) {
    this.customInjector = Injector.create({
      parent: injector,
      providers: [
        {
          provide: SOME_TOKEN,
          useValue: 'Some value',
        },
      ],
    });
  }
}
```

```ts
import { Inject } from "@angular/core";
import { SOME_TOKEN } from './tokens';

export class ChildComponent {
  constructor(@Inject(SOME_TOKEN) token: string) {}
}
```

---

## Use with TemplateRef
In this case `*ngxContentOutlet` inserts an embedded view from a prepared `TemplateRef`
```html
<ng-container *ngxContentOutlet="templateRef"></ng-container>

<ng-template #templateRef>
  <div>
    <p> Well, that's where we met! </p>
  </div>
</ng-template>
```

### Use with a context object

Also, you can attach a context object to the `EmbeddedViewRef` by `context` option.
```html
<ng-container *ngxContentOutlet="templateRef; context: context"></ng-container>

<ng-template #templateRef let-name let-message="message">
  <div>
    <p> {{name}}, {{message}} </p>
  </div>
</ng-template>
```
> **_NOTE:_** Using the key `$implicit` in the context object will set its value as default. [Read more](https://angular.io/api/common/NgTemplateOutlet#properties)
```ts
export class AppComponent {
  readonly context = { $implicit: 'Houston', message: 'we have a problem' };
}
```

### Use with optional custom injector

You can pass a custom injector to be used within the embedded view.

#### ParentComponent
```html
<!--- ParentComponent provides his own injector to the content --->
<ng-container *ngxContentOutlet="content as implicit; injector: parentInjector">
  {{ implicit }}
</ng-container>
```
```ts
import { inject, Input } from "@angular/core";
import { ReflectiveContent } from "@coreteq/ngx-projection";

export class ParentComponent {
  @Input()
  content: ReflectiveContent<any>;

  parentInjector = inject(Injector);
}
```
> **_NOTE:_** See [ReflectiveContent](#api) type
#### AppComponent
```html
<app-parent [content]="templateRef"></app-parent>

<!--- Currently the parent injector for the ChildComponent is an injector of the AppComponent --->
<ng-template #templateRef>
  <app-child></app-child>
</ng-template>
```
#### ChildComponent
```ts
import { ParentComponent } from "./parent.component";
import { Inject } from "@angular/core";

export class ChildComponent {
  constructor(@Inject(ParentComponent) parent: ParentComponent) {}
}
```

---

## Use with primitive type value

And finally `*ngxContentOutlet` directive allows to use interpolation to display the primitive value. Thanks to `as` keyword, you can assign to another variable result of ngxContentOutlet.
```html
<ng-container *ngxContentOutlet="value as content">
  {{ content }}
</ng-container>
```
```ts
export class AppComponent {
  // primitive 'string'
  // also *ngxContentOutlet accepts 'number', 'undefined' and 'null'
  value = 'A Cold Day in Hell';
}
```

# API

| Input                            | Type                          | Default | Required | Description |
|----------------------------------|-------------------------------| ------- | -------- | ----------- |
| ```[ngxContentOutlet]```         | ```ReflectiveContent<T>```    | n/a     | yes      |             |
| ```[ngxContentOutletContext]```  | ```Record<string, unknown>``` | n/a     | no       |             |
| ```[ngxContentOutletInjector]``` | ```Injector```                | n/a     | no       |             |
| ```[ngxContentOutletContent]```  | ```any[][]```                 | n/a     | no       |             |

`ReflectiveContent` is a union type:
>   ```
> export type ReflectiveContent<T> =
>   | Type<T>
>   | TemplateRef<Partial<T>>
>   | string
>   | number
>   | null
>   | undefined;

---
_Source: https://npm.io/package/@coreteq/ngx-projection · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
