Skip to content

Commit c333db0

Browse files
committed
feat(elements): redesign api with async elements support
1 parent bf01fd3 commit c333db0

2 files changed

Lines changed: 26 additions & 36 deletions

File tree

packages/elements/src/element-registry.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ import { isPlatformBrowser } from '@angular/common';
22
import { inject, InjectionToken, PLATFORM_ID } from '@angular/core';
33

44
/**
5-
* Injection Token for the ECMA `CustomElementRegistry` instance.
6-
* @remarks Injecting this token on non-browser platforms will result in an error.
5+
* Injection Token for the ECMA `CustomElementRegistry` instance, or
6+
* `null` if the current platform is not browser.
77
* @see https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry
88
*/
9-
export const ELEMENT_REGISTRY = new InjectionToken<CustomElementRegistry>(
10-
'ELEMENT_REGISTRY',
11-
{
9+
export const ELEMENT_REGISTRY =
10+
new InjectionToken<CustomElementRegistry | null>('ELEMENT_REGISTRY', {
1211
factory: () => {
1312
const platform = inject(PLATFORM_ID);
14-
if (!isPlatformBrowser(platform))
15-
throw new Error(`illegal access of ELEMENT_REGISTRY`);
13+
if (!isPlatformBrowser(platform)) return null;
1614
return window.customElements;
1715
},
18-
},
19-
);
16+
});

packages/elements/src/provide.ts

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,51 @@
1-
import { isPlatformBrowser } from '@angular/common';
21
import {
32
EnvironmentProviders,
43
inject,
54
Injector,
65
provideEnvironmentInitializer,
76
} from '@angular/core';
87
import { createCustomElement } from '@angular/elements';
9-
import { usePlatformOnly } from '@angularity/core';
108

119
import { ELEMENT_REGISTRY } from './element-registry';
1210
import { Elements } from './elements';
1311

1412
/**
15-
* Offers a declarative approach to register Angular Elements in the browser platform.
13+
* Offers a declarative approach to register Angular Elements.
1614
*
17-
* @remarks The returned providers are for `EnvironmentInjector` only, e.g. `app.config.ts`,
18-
* route declarations, and NgModules. The registered Angular Elements will not be unregistered
19-
* when the `EnvironmentInjector` is destroyed, so make sure the `EnvironmentInjector` will not
20-
* be destroyed anytime in the application's lifecycle.
15+
* The elements can be either provided synchronously or asynchronously
16+
* via a promise.
2117
*
22-
* @remarks If the current platform is not browser, this is a noop.
18+
* @remarks Noop if the current platform is not browser.
2319
*
2420
* @example
2521
* ```ts
26-
* export const APP_ELEMENTS: Elements = {
22+
* export const appElements: Elements = {
2723
* 'my-button': ButtonComponent,
2824
* 'my-icon': IconComponent,
2925
* 'my-icon-button': IconButtonComponent,
3026
* };
3127
* ```
3228
* ```ts
3329
* providers: [
34-
* provideElements({ elements: APP_ELEMENTS }),
30+
* provideElements(appElements),
31+
* ]
32+
* ```
33+
* ```ts
34+
* providers: [
35+
* provideElements(import('./app-elements').then(m => m.appElements)),
3536
* ]
3637
* ```
3738
*/
3839
export function provideElements(
39-
config: ProvideElementsConfig,
40+
elements: Elements | Promise<Elements>,
4041
): EnvironmentProviders {
41-
return provideEnvironmentInitializer(() => {
42-
usePlatformOnly(isPlatformBrowser, () => {
43-
const registry = inject(ELEMENT_REGISTRY);
44-
const injector = inject(Injector);
45-
for (const [name, type] of Object.entries(config.elements)) {
46-
const element = createCustomElement(type, { injector });
47-
registry.define(name, element);
48-
}
49-
});
42+
return provideEnvironmentInitializer(async () => {
43+
const registry = inject(ELEMENT_REGISTRY);
44+
if (!registry) return;
45+
const injector = inject(Injector);
46+
for (const [name, type] of Object.entries(await elements)) {
47+
const element = createCustomElement(type, { injector });
48+
registry.define(name, element);
49+
}
5050
});
5151
}
52-
53-
/**
54-
* @see `provideElements`
55-
*/
56-
export interface ProvideElementsConfig {
57-
elements: Elements;
58-
}

0 commit comments

Comments
 (0)