Skip to content

Commit 0832c9f

Browse files
committed
feat(theming): rework facade api
1 parent 535dae9 commit 0832c9f

3 files changed

Lines changed: 40 additions & 56 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { ProviderToken } from '@angular/core';
2+
3+
import { ThemeBuilder, ThemeBuilderConfigOf } from './builder';
4+
5+
export interface ThemeBuilderComposition {
6+
builder: ProviderToken<ThemeBuilder<any>>;
7+
config: unknown;
8+
}
9+
10+
export const withThemeBuilder = <Builder extends ThemeBuilder<any>>(
11+
builder: ProviderToken<Builder>,
12+
config: ThemeBuilderConfigOf<Builder>,
13+
): ThemeBuilderComposition => ({
14+
builder,
15+
config,
16+
});

packages/theming/src/builder.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ export interface ThemeBuilderContext<Config> {
88
name: string;
99
config: Config;
1010
}
11+
12+
export type ThemeBuilderConfigOf<Builder extends ThemeBuilder<any>> =
13+
Builder extends ThemeBuilder<infer Config> ? Config : never;

packages/theming/src/manager.ts

Lines changed: 21 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,34 @@
1-
import {
2-
forwardRef,
3-
inject,
4-
Injectable,
5-
Injector,
6-
ProviderToken,
7-
} from '@angular/core';
1+
import { inject, Injectable, Injector } from '@angular/core';
82

9-
import { ThemeBuilder } from './builder';
3+
import { ThemeBuilderComposition } from './builder-composition';
104
import { ThemeTokenRegistry, ThemeTokens } from './token';
115

12-
@Injectable({
13-
providedIn: 'root',
14-
useExisting: forwardRef(() => SimpleThemeManager),
15-
})
16-
export abstract class ThemeManager {
17-
abstract buildAndApply<Builders extends ThemeBuilderMap>(
18-
builders: Builders,
19-
configs: ThemeBuilderConfigMapOf<Builders>,
20-
): void;
21-
abstract build<Builders extends ThemeBuilderMap>(
22-
builders: Builders,
23-
configs: ThemeBuilderConfigMapOf<Builders>,
24-
): ThemeTokens;
25-
abstract apply(tokens: ThemeTokens): void;
26-
}
27-
28-
export interface ThemeBuilderMap {
29-
[name: string]: ProviderToken<ThemeBuilder<unknown>>;
30-
}
31-
32-
export type ThemeBuilderConfigMapOf<Builders extends ThemeBuilderMap> = {
33-
[Name in keyof Builders]: Builders[Name] extends ProviderToken<
34-
ThemeBuilder<infer Config>
35-
>
36-
? Config
37-
: never;
38-
};
39-
406
@Injectable({ providedIn: 'root' })
41-
export class SimpleThemeManager implements ThemeManager {
7+
export class ThemeManager {
428
protected injector = inject(Injector);
439
protected tokens = inject(ThemeTokenRegistry);
4410

45-
buildAndApply<Builders extends ThemeBuilderMap>(
46-
builders: Builders,
47-
configs: ThemeBuilderConfigMapOf<Builders>,
48-
): void {
49-
const tokens = this.build(builders, configs);
50-
this.apply(tokens);
51-
}
52-
53-
build<Builders extends ThemeBuilderMap>(
54-
builders: Builders,
55-
configs: ThemeBuilderConfigMapOf<Builders>,
56-
): ThemeTokens {
57-
return Object.entries(builders).reduce(
58-
(tokens, [name, builder]) => ({
59-
...tokens,
60-
...this.injector.get(builder).build({ name, config: configs[name] }),
61-
}),
62-
{},
63-
);
11+
build(config: ThemeBuildConfig): ThemeTokens {
12+
const tokens: ThemeTokens = {};
13+
for (const [name, composition] of Object.entries(config)) {
14+
const { builder: token, config } = composition;
15+
const builder = this.injector.get(token);
16+
const result = builder.build({ name, config });
17+
Object.assign(tokens, result);
18+
}
19+
return tokens;
6420
}
6521

6622
apply(tokens: ThemeTokens): void {
6723
for (const name in tokens) this.tokens.set(name, tokens[name]);
6824
}
25+
26+
buildAndApply(config: ThemeBuildConfig): void {
27+
const tokens = this.build(config);
28+
this.apply(tokens);
29+
}
30+
}
31+
32+
export interface ThemeBuildConfig {
33+
[name: string]: ThemeBuilderComposition;
6934
}

0 commit comments

Comments
 (0)