@udixio/theme 1.0.0-beta.6 → 1.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/app.service.d.ts +6 -3
  2. package/dist/color/color.interface.d.ts +1 -2
  3. package/dist/color/entities/color.entity.d.ts +6 -1
  4. package/dist/color/index.d.ts +1 -2
  5. package/dist/color/models/default-color.model.d.ts +2 -3
  6. package/dist/color/services/color-manager.service.d.ts +18 -0
  7. package/dist/color/services/color.service.d.ts +21 -0
  8. package/dist/color/services/index.d.ts +2 -0
  9. package/dist/config/config.interface.d.ts +14 -0
  10. package/dist/config/config.module.d.ts +2 -0
  11. package/dist/config/config.service.d.ts +12 -0
  12. package/dist/config/index.d.ts +2 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/main.d.ts +2 -1
  15. package/dist/plugin/plugin.abstract.d.ts +6 -0
  16. package/dist/plugin/plugin.module.d.ts +2 -0
  17. package/dist/plugin/plugin.service.d.ts +9 -0
  18. package/dist/theme/entities/variant.entity.d.ts +2 -1
  19. package/dist/theme/services/scheme.service.d.ts +7 -2
  20. package/dist/theme/services/theme.service.d.ts +10 -4
  21. package/dist/theme/services/variant.service.d.ts +4 -0
  22. package/dist/theme.cjs.development.js +1077 -506
  23. package/dist/theme.cjs.development.js.map +1 -1
  24. package/dist/theme.cjs.production.min.js +1 -1
  25. package/dist/theme.cjs.production.min.js.map +1 -1
  26. package/dist/theme.esm.js +1073 -507
  27. package/dist/theme.esm.js.map +1 -1
  28. package/package.json +3 -5
  29. package/src/app.container.ts +9 -1
  30. package/src/app.service.ts +8 -2
  31. package/src/color/color.interface.ts +1 -3
  32. package/src/color/color.module.ts +2 -2
  33. package/src/color/entities/color.entity.ts +13 -1
  34. package/src/color/index.ts +1 -2
  35. package/src/color/models/default-color.model.ts +205 -202
  36. package/src/color/{color-manager.service.ts → services/color-manager.service.ts} +17 -10
  37. package/src/color/{color.service.spec.ts → services/color.service.spec.ts} +1 -1
  38. package/src/color/{color.service.ts → services/color.service.ts} +33 -21
  39. package/src/color/services/index.ts +2 -0
  40. package/src/config/config.interface.ts +15 -0
  41. package/src/config/config.module.ts +7 -0
  42. package/src/config/config.service.ts +68 -0
  43. package/src/config/index.ts +2 -0
  44. package/src/index.ts +3 -0
  45. package/src/main.ts +9 -1
  46. package/src/plugin/plugin.abstract.ts +7 -0
  47. package/src/plugin/plugin.module.ts +7 -0
  48. package/src/plugin/plugin.service.ts +26 -0
  49. package/src/theme/entities/variant.entity.ts +2 -1
  50. package/src/theme/models/variant.model.ts +7 -0
  51. package/src/theme/services/scheme.service.ts +39 -9
  52. package/src/theme/services/theme.service.ts +18 -8
  53. package/src/theme/services/variant.service.ts +36 -2
  54. package/dist/color/color-manager.service.d.ts +0 -17
  55. package/dist/color/color.service.d.ts +0 -16
@@ -0,0 +1,7 @@
1
+ import { asClass } from 'awilix';
2
+ import { Module } from '../app.container';
3
+ import { ConfigService } from './config.service';
4
+
5
+ export const ConfigModule: Module = {
6
+ configService: asClass(ConfigService).singleton(),
7
+ };
@@ -0,0 +1,68 @@
1
+ import { ConfigInterface } from './config.interface';
2
+
3
+ import { resolve } from 'path';
4
+ import { defaultColors } from '../color';
5
+ import { VariantModel } from '../theme';
6
+ import { AppService } from '../app.service';
7
+
8
+ export function defineConfig(configObject: ConfigInterface): ConfigInterface {
9
+ if (!configObject || typeof configObject !== 'object') {
10
+ throw new Error('The configuration is missing or not an object');
11
+ }
12
+ if (!('sourceColor' in configObject)) {
13
+ throw new Error('Invalid configuration');
14
+ }
15
+ return configObject as ConfigInterface;
16
+ }
17
+
18
+ export class ConfigService {
19
+ configPath = './theme.config.ts';
20
+
21
+ private appService: AppService;
22
+
23
+ constructor({ appService }: { appService: AppService }) {
24
+ this.appService = appService;
25
+ }
26
+
27
+ public async loadConfig(): Promise<void> {
28
+ const { themeService, colorService, pluginService } = this.appService;
29
+ const {
30
+ sourceColor,
31
+ contrastLevel = 0,
32
+ isDark = false,
33
+ variant = VariantModel.tonalSpot,
34
+ palettes,
35
+ colors,
36
+ useDefaultColors = true,
37
+ plugins,
38
+ } = await this.getConfig();
39
+ themeService.create({
40
+ contrastLevel: contrastLevel,
41
+ isDark: isDark,
42
+ sourceColorHex: sourceColor,
43
+ variant: variant,
44
+ });
45
+ if (palettes) {
46
+ Object.entries(palettes).forEach(([key, value]) =>
47
+ themeService.addCustomPalette(key, value)
48
+ );
49
+ }
50
+ if (useDefaultColors) {
51
+ colorService.addColors(defaultColors);
52
+ }
53
+ if (colors) {
54
+ colorService.addColors(colors);
55
+ }
56
+ if (plugins) {
57
+ plugins.forEach((plugin) => pluginService.addPlugin(plugin));
58
+ pluginService.loadPlugins(this.appService);
59
+ }
60
+ }
61
+
62
+ private async getConfig(): Promise<ConfigInterface> {
63
+ const path = resolve(this.configPath);
64
+ const configImport = await import(path);
65
+ const config: unknown = configImport.default;
66
+ return config as ConfigInterface;
67
+ }
68
+ }
@@ -0,0 +1,2 @@
1
+ export * from './config.interface';
2
+ export * from './config.service';
package/src/index.ts CHANGED
@@ -1,6 +1,9 @@
1
+ export { default as AppContainer } from './app.container';
1
2
  export * from './app.container';
3
+ export * from './app.module';
2
4
  export * from './app.service';
3
5
  export * from './color';
6
+ export * from './config';
4
7
  export * from './main';
5
8
  export * from './material-color-utilities';
6
9
  export * from './theme';
package/src/main.ts CHANGED
@@ -1,6 +1,14 @@
1
1
  import AppContainer from './app.container';
2
2
  import { AppService } from './app.service';
3
+ import { ConfigService } from './config';
3
4
 
4
- export function main(): AppService {
5
+ export function bootstrap(): AppService {
6
+ return AppContainer.resolve<AppService>('appService');
7
+ }
8
+
9
+ export async function bootstrapFromConfig(path?: string): Promise<AppService> {
10
+ const configService = AppContainer.resolve<ConfigService>('configService');
11
+ if (path) configService.configPath = path;
12
+ await configService.loadConfig();
5
13
  return AppContainer.resolve<AppService>('appService');
6
14
  }
@@ -0,0 +1,7 @@
1
+ import { AppService } from '../app.service';
2
+
3
+ export abstract class PluginAbstract {
4
+ static dependencies: (new () => PluginAbstract)[];
5
+
6
+ protected constructor(protected appService: AppService) {}
7
+ }
@@ -0,0 +1,7 @@
1
+ import { asClass } from 'awilix';
2
+ import { Module } from '../app.container';
3
+ import { PluginService } from './plugin.service';
4
+
5
+ export const PluginModule: Module = {
6
+ pluginService: asClass(PluginService).singleton(),
7
+ };
@@ -0,0 +1,26 @@
1
+ import { PluginAbstract } from './plugin.abstract';
2
+ import { AppService } from '../app.service';
3
+
4
+ export class PluginService {
5
+ private pluginInstances = new Map<string, PluginAbstract>();
6
+ private pluginConstructors = new Map<
7
+ string,
8
+ new (appService: AppService) => PluginAbstract
9
+ >();
10
+
11
+ public addPlugin(plugin: new (appService: AppService) => PluginAbstract) {
12
+ this.pluginConstructors.set(plugin.name, plugin);
13
+ }
14
+
15
+ public loadPlugins(appService: AppService) {
16
+ this.pluginConstructors.forEach((plugin) => {
17
+ this.pluginInstances.set(plugin.name, new plugin(appService));
18
+ });
19
+ }
20
+
21
+ public getPlugin<T extends PluginAbstract>(
22
+ plugin: new (appService: AppService) => T
23
+ ): T | undefined {
24
+ return this.pluginInstances.get(plugin.name) as T;
25
+ }
26
+ }
@@ -33,6 +33,7 @@ export const getRotatedHue = (
33
33
 
34
34
  export class VariantEntity {
35
35
  constructor(
36
- public palettes: Record<string, (sourceColorHct: Hct) => TonalPalette> = {}
36
+ public palettes: Record<string, (sourceColorHct: Hct) => TonalPalette> = {},
37
+ public customPalettes?: (colorHct: Hct) => TonalPalette
37
38
  ) {}
38
39
  }
@@ -21,6 +21,8 @@ export class VariantModel {
21
21
  neutralVariant: (sourceColorHct) =>
22
22
  TonalPalette.fromHueAndChroma(sourceColorHct.hue, 8.0),
23
23
  },
24
+ customPalettes: (colorHct) =>
25
+ TonalPalette.fromHueAndChroma(colorHct.hue, 16),
24
26
  };
25
27
  static vibrant: VariantEntity = {
26
28
  palettes: {
@@ -41,6 +43,11 @@ export class VariantModel {
41
43
  neutralVariant: (sourceColorHct) =>
42
44
  TonalPalette.fromHueAndChroma(sourceColorHct.hue, 8.0),
43
45
  },
46
+ customPalettes: (colorHct) =>
47
+ TonalPalette.fromHueAndChroma(
48
+ getRotatedHue(colorHct, this.hues, this.secondaryRotations),
49
+ 24.0
50
+ ),
44
51
  };
45
52
 
46
53
  private static readonly hues = [
@@ -4,14 +4,19 @@ import {
4
4
  Hct,
5
5
  TonalPalette,
6
6
  } from '@material/material-color-utilities';
7
- import mergeDeep from 'merge-deep';
8
7
 
9
8
  export type SchemeServiceOptions = Omit<
10
9
  SchemeOptions,
11
10
  'palettes' | 'sourceColorArgb'
12
11
  > & {
13
- sourceColorHex: string;
14
- palettes: Record<string, (sourceColorHct: Hct) => TonalPalette>;
12
+ sourcesColorHex: Record<string, string> & { primary?: string };
13
+ palettes: Record<
14
+ string,
15
+ {
16
+ sourceColorkey?: string;
17
+ tonalPalette: (sourceColorHct: Hct) => TonalPalette;
18
+ }
19
+ >;
15
20
  };
16
21
 
17
22
  export class SchemeService {
@@ -19,19 +24,44 @@ export class SchemeService {
19
24
  private options?: SchemeServiceOptions;
20
25
 
21
26
  createOrUpdate(options: Partial<SchemeServiceOptions>) {
22
- this.options = mergeDeep(options, this.options);
27
+ this.options = {
28
+ ...this.options,
29
+ ...options,
30
+ sourcesColorHex: {
31
+ ...this.options?.sourcesColorHex,
32
+ ...options.sourcesColorHex,
33
+ },
34
+ palettes: {
35
+ ...this.options?.palettes,
36
+ ...options.palettes,
37
+ },
38
+ } as SchemeServiceOptions;
23
39
  const palettes = new Map<string, TonalPalette>();
24
40
 
25
- const sourceColorArgb = argbFromHex(this.options.sourceColorHex);
41
+ if (!this.options.sourcesColorHex.primary) {
42
+ throw new Error('Primary source color is not set');
43
+ }
44
+
45
+ const sourceColorArgb = argbFromHex(this.options.sourcesColorHex.primary);
26
46
  const sourceColorHct: Hct = Hct.fromInt(sourceColorArgb);
27
47
 
28
48
  if (!this.options.palettes) {
29
49
  return;
30
50
  }
31
- for (const [key, paletteFunction] of Object.entries(
32
- this.options.palettes
33
- )) {
34
- const palette: TonalPalette = paletteFunction(sourceColorHct);
51
+ for (const [
52
+ key,
53
+ { sourceColorkey, tonalPalette: paletteFunction },
54
+ ] of Object.entries(this.options.palettes)) {
55
+ let palette: TonalPalette;
56
+ if (!sourceColorkey) {
57
+ palette = paletteFunction(sourceColorHct);
58
+ } else {
59
+ const sourceColorArgb = argbFromHex(
60
+ this.options.sourcesColorHex[sourceColorkey]
61
+ );
62
+ const sourceColorHct: Hct = Hct.fromInt(sourceColorArgb);
63
+ palette = paletteFunction(sourceColorHct);
64
+ }
35
65
  palettes.set(key, palette);
36
66
  }
37
67
  this.schemeEntity = new SchemeEntity({
@@ -3,7 +3,10 @@ import { SchemeService, SchemeServiceOptions } from './scheme.service';
3
3
  import { VariantService } from './variant.service';
4
4
  import { VariantEntity } from '../entities/variant.entity';
5
5
 
6
- type ThemeOptions = Omit<SchemeServiceOptions, 'palettes'>;
6
+ type ThemeOptions = Omit<
7
+ SchemeServiceOptions,
8
+ 'palettes' | 'sourcesColorHex'
9
+ > & { sourceColorHex: string };
7
10
 
8
11
  const colorPaletteKeyColor = DynamicColor.fromPalette({
9
12
  name: 'primary_palette_key_color',
@@ -47,16 +50,23 @@ export class ThemeService {
47
50
  // return this.theme();
48
51
  // }
49
52
 
50
- create(options: ThemeOptions) {
51
- this.schemeService.createOrUpdate(options);
53
+ create(options: ThemeOptions & { variant: VariantEntity }) {
54
+ this.schemeService.createOrUpdate({
55
+ ...options,
56
+ sourcesColorHex: { primary: options.sourceColorHex },
57
+ });
58
+ this.variantService.set(options.variant);
52
59
  }
53
60
 
54
- addVariant(variant: VariantEntity) {
55
- this.variantService.set(variant);
61
+ update(options: Partial<ThemeOptions> & { variant?: VariantEntity }) {
62
+ const themeOptions: Partial<SchemeServiceOptions> = { ...options };
63
+ if (options.sourceColorHex)
64
+ themeOptions.sourcesColorHex = { primary: options.sourceColorHex };
65
+ this.schemeService.createOrUpdate(themeOptions);
66
+ if (options.variant) this.variantService.set(options.variant);
56
67
  }
57
-
58
- update(options: Partial<ThemeOptions>) {
59
- this.schemeService.createOrUpdate(options);
68
+ addCustomPalette(key: string, colorHex: string) {
69
+ this.variantService.addCustomPalette(key, colorHex);
60
70
  }
61
71
  // theme(): SchemeService {
62
72
  // return new SchemeService(this.themeOptions, this.colorService)
@@ -1,18 +1,52 @@
1
1
  import { SchemeService } from './scheme.service';
2
2
  import { VariantEntity } from '../entities/variant.entity';
3
- import { TonalPalette } from '@material/material-color-utilities';
3
+ import { Hct, TonalPalette } from '@material/material-color-utilities';
4
4
 
5
5
  export class VariantService {
6
+ public customPalettes: Record<string, string> = {};
7
+ private variantEntity?: VariantEntity;
8
+
6
9
  private readonly schemeService: SchemeService;
7
10
  constructor({ schemeService }: { schemeService: SchemeService }) {
8
11
  this.schemeService = schemeService;
9
12
  }
10
13
 
14
+ addCustomPalette(key: string, colorHex: string) {
15
+ this.customPalettes[key] = colorHex;
16
+ this.update();
17
+ }
18
+
11
19
  set(variantEntity: VariantEntity) {
20
+ this.variantEntity = variantEntity;
12
21
  if (!variantEntity.palettes.error) {
13
22
  variantEntity.palettes.error = () =>
14
23
  TonalPalette.fromHueAndChroma(25.0, 84.0);
15
24
  }
16
- this.schemeService.createOrUpdate(variantEntity);
25
+ this.update();
26
+ }
27
+ private update() {
28
+ if (!this.variantEntity) return;
29
+ const palettes: Record<
30
+ string,
31
+ {
32
+ sourceColorkey?: string;
33
+ tonalPalette: (sourceColorHct: Hct) => TonalPalette;
34
+ }
35
+ > = {};
36
+ Object.keys(this.variantEntity.palettes).forEach((key) => {
37
+ palettes[key] = { tonalPalette: this.variantEntity!.palettes[key] };
38
+ });
39
+ if (this.variantEntity.customPalettes) {
40
+ Object.keys(this.customPalettes).forEach((key) => {
41
+ palettes[key] = {
42
+ sourceColorkey: key,
43
+ tonalPalette: this.variantEntity!.customPalettes!,
44
+ };
45
+ });
46
+ }
47
+ this.schemeService.createOrUpdate({
48
+ sourcesColorHex: this.customPalettes,
49
+ palettes: palettes,
50
+ });
17
51
  }
18
52
  }
@@ -1,17 +0,0 @@
1
- import { DynamicColor } from '../material-color-utilities/dynamic_color';
2
- import { SchemeEntity } from '../theme/entities/scheme.entity';
3
- import { ColorEntity, ColorOptions } from './entities/color.entity';
4
- import { SchemeService } from '../theme/services/scheme.service';
5
- export declare const highestSurface: (s: SchemeEntity, colorManagerService: ColorManagerService) => DynamicColor;
6
- export declare class ColorManagerService {
7
- private colorMap;
8
- private readonly schemeService;
9
- constructor({ schemeService }: {
10
- schemeService: SchemeService;
11
- });
12
- createOrUpdate(key: string, args: Partial<ColorOptions>): ColorEntity;
13
- remove(key: string): boolean;
14
- get(key: string): ColorEntity;
15
- getAll(): ReadonlyMap<string, ColorEntity>;
16
- addFromPalette(key: string): void;
17
- }
@@ -1,16 +0,0 @@
1
- import { ColorManagerService } from './color-manager.service';
2
- import { ColorInterface } from './color.interface';
3
- import { ColorEntity, ColorOptions } from './entities/color.entity';
4
- export declare class ColorService implements ColorInterface {
5
- private readonly colorManagerService;
6
- constructor({ colorManagerService, }: {
7
- colorManagerService: ColorManagerService;
8
- });
9
- getAllColors(): ReadonlyMap<string, ColorEntity>;
10
- addBaseColors(): void;
11
- addColor(key: string, color: ColorOptions): ColorEntity;
12
- addColors(colors: Record<string, ColorOptions>): ColorEntity[];
13
- getColor(key: string): ColorEntity;
14
- removeColor(key: string): boolean;
15
- updateColor(key: string, newColor: Partial<ColorOptions>): ColorEntity;
16
- }