Skip to content

Commit 3824230

Browse files
authored
feat(standalone-apis): cover library exports (#6)
1 parent b74bf38 commit 3824230

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Exporting standalone components from Angular libraries
2+
3+
## Exporting unrelated standalone components from Angular libraries
4+
5+
Libraries export standalone components, directives, and pipes directly from their public API, usually an `index.ts` or `public_api.ts` file:
6+
7+
```ts
8+
export * from "./lib/our-button.component";
9+
export * from "./lib/our-checkbox.component";
10+
```
11+
12+
Standalone components consuming the library import the components through their `imports` array:
13+
14+
```ts
15+
import { Component } from "@angular/core";
16+
import { OurButtonComponent } from "@our-org/our-lib";
17+
18+
import { RocketService } from "./rocket.service";
19+
20+
@Component({
21+
imports: [OurButtonComponent],
22+
standalone: true,
23+
template: `<our-button (click)="onRocketLaunch()">Launch rocket</our-button>`,
24+
})
25+
export class RocketComponent {
26+
#rocket: RocketService;
27+
28+
constructor(rocket: RocketService) {
29+
this.#rocket = rocket;
30+
}
31+
32+
onRocketLaunch(): void {
33+
this.#rocket.launch();
34+
}
35+
}
36+
```
37+
38+
### Interoperability with NgModules
39+
40+
Legacy components depending add the standalone component to their NgModule's `imports` array:
41+
42+
```ts
43+
import { Component, NgModule } from "@angular/core";
44+
import { OurButtonComponent } from "@our-org/our-lib";
45+
46+
import { RocketService } from "./rocket.service";
47+
48+
@Component({
49+
template: `<our-button (click)="onRocketLaunch()">Launch rocket</our-button>`,
50+
})
51+
export class RocketComponent {
52+
#rocket: RocketService;
53+
54+
constructor(rocket: RocketService) {
55+
this.#rocket = rocket;
56+
}
57+
58+
onRocketLaunch(): void {
59+
this.#rocket.launch();
60+
}
61+
}
62+
63+
@NgModule({
64+
declarations: [RocketComponent],
65+
exports: [RocketComponent],
66+
imports: [OurButtonComponent],
67+
})
68+
export class RocketModule {}
69+
```
70+
71+
## Exporting cohesive standalone components from Angular libraries
72+
73+
In case multiple components, directive, and pipes are always used together, we export them in an array from our library's public API:
74+
75+
```ts
76+
import { OurTableCellComponent } from "./lib/table/our-table-cell.component";
77+
import { OurTableRowComponent } from "./lib/table/our-table-row.component";
78+
import { OurTableComponent } from "./lib/table/our-table.component";
79+
80+
import type { Type } from "@angular/core";
81+
82+
// (Optionally) export the individual types for selective importing and
83+
// referencing instances for queries and similar purposes
84+
export OurTableCellComponent;
85+
export OurTableRowComponent;
86+
export OurTableComponent;
87+
88+
// Export cohesive standalone declarables for easy importing
89+
export type OurTableType = OurTableCellComponent | OurTableRowComponent | OurTableComponent;
90+
export const ourTableImports: Type<OurTableType>[] = [
91+
OurTableCellComponent,
92+
OurTableRowComponent,
93+
OurTableComponent,
94+
];
95+
```
96+
97+
Standalone components consuming the library import the components through their `imports` array:
98+
99+
```ts
100+
import { CommonModule } from "@angular/common";
101+
import { Component } from "@angular/core";
102+
import { ourTableImports } from "@our-org/our-lib";
103+
104+
import { DataGridService } from "./data-grid.service";
105+
106+
@Component({
107+
imports: [CommonModule, ourTableImports],
108+
standalone: true
109+
template: `
110+
<our-table>
111+
<our-table-row *ngFor="let row of rows$ | async">
112+
<our-table-cell *ngFor="let cell of row.cells">
113+
{{ cell.text }}
114+
</our-table-cell>
115+
</our-table>
116+
`,
117+
})
118+
export class DataGridComponent {
119+
rows$ =
120+
121+
constructor(dataGridService: DataGridService) {
122+
this.rows$ = dataGridService.rows$;
123+
}
124+
}
125+
```
126+
127+
### Interoperability with NgModules
128+
129+
Legacy components depending add the exported components to their NgModule's `imports` array:
130+
131+
```ts
132+
import { CommonModule } from "@angular/common";
133+
import { Component, NgModule } from "@angular/core";
134+
import { ourTableImports } from "@our-org/our-lib";
135+
136+
import { DataGridService } from "./data-grid.service";
137+
138+
@Component({
139+
imports: [CommonModule, ourTableImports],
140+
standalone: true
141+
template: `
142+
<our-table>
143+
<our-table-row *ngFor="let row of rows$ | async">
144+
<our-table-cell *ngFor="let cell of row.cells">
145+
{{ cell.text }}
146+
</our-table-cell>
147+
</our-table>
148+
`,
149+
})
150+
export class DataGridComponent {
151+
rows$ =
152+
153+
constructor(dataGridService: DataGridService) {
154+
this.rows$ = dataGridService.rows$;
155+
}
156+
}
157+
158+
@NgModule({
159+
declarations: [DataGridComponent],
160+
exports: [DataGridComponent],
161+
imports: [CommonModule, ourTableImports]
162+
})
163+
export class DataGridModule {}
164+
```

0 commit comments

Comments
 (0)