@udixio/theme 1.3.1 → 2.0.0

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 (139) hide show
  1. package/CHANGELOG.md +8 -3
  2. package/dist/API.d.ts +7 -4
  3. package/dist/API.d.ts.map +1 -1
  4. package/dist/app.container.d.ts +1 -2
  5. package/dist/app.container.d.ts.map +1 -1
  6. package/dist/bin.cjs +1 -1
  7. package/dist/bin.js +1 -1
  8. package/dist/browser.cjs +22 -18
  9. package/dist/browser.js +32 -28
  10. package/dist/color/color.api.d.ts +11 -30
  11. package/dist/color/color.api.d.ts.map +1 -1
  12. package/dist/color/color.d.ts +99 -0
  13. package/dist/color/color.d.ts.map +1 -0
  14. package/dist/color/color.manager.d.ts +9 -17
  15. package/dist/color/color.manager.d.ts.map +1 -1
  16. package/dist/color/color.utils.d.ts +14 -3
  17. package/dist/color/color.utils.d.ts.map +1 -1
  18. package/dist/color/default-color.d.ts.map +1 -1
  19. package/dist/color/index.d.ts +1 -1
  20. package/dist/color/index.d.ts.map +1 -1
  21. package/dist/config/config.interface.d.ts +4 -4
  22. package/dist/config/config.interface.d.ts.map +1 -1
  23. package/dist/context/context.d.ts +41 -0
  24. package/dist/context/context.d.ts.map +1 -0
  25. package/dist/context/context.module.d.ts +3 -0
  26. package/dist/context/context.module.d.ts.map +1 -0
  27. package/dist/context/index.d.ts +3 -0
  28. package/dist/context/index.d.ts.map +1 -0
  29. package/dist/font.plugin-BZ-TTeTo.cjs +227 -0
  30. package/dist/font.plugin-DZtMajJV.js +228 -0
  31. package/dist/index.d.ts +6 -4
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/{load-from-path-DoZnR1-p.cjs → load-from-path-DZ35yiXK.cjs} +2 -2
  34. package/dist/{load-from-path-Bo1kCfh9.js → load-from-path-Dobe0beV.js} +1 -1
  35. package/dist/loader/loader.d.ts +1 -1
  36. package/dist/loader/loader.d.ts.map +1 -1
  37. package/dist/{loader-C8_TyOuS.js → loader-BS_Esfwg.js} +1408 -908
  38. package/dist/{loader-R7hccp8_.cjs → loader-C8LnOoqg.cjs} +1392 -892
  39. package/dist/material-color-utilities/dynamic_color.d.ts +0 -22
  40. package/dist/material-color-utilities/dynamic_color.d.ts.map +1 -1
  41. package/dist/material-color-utilities/toneDeltaPair.d.ts +8 -8
  42. package/dist/material-color-utilities/toneDeltaPair.d.ts.map +1 -1
  43. package/dist/node.cjs +23 -19
  44. package/dist/node.js +34 -30
  45. package/dist/palette/index.d.ts +4 -0
  46. package/dist/palette/index.d.ts.map +1 -0
  47. package/dist/palette/palette.api.d.ts +13 -0
  48. package/dist/palette/palette.api.d.ts.map +1 -0
  49. package/dist/palette/palette.d.ts +33 -0
  50. package/dist/palette/palette.d.ts.map +1 -0
  51. package/dist/palette/palette.manager.d.ts +20 -0
  52. package/dist/palette/palette.manager.d.ts.map +1 -0
  53. package/dist/palette/palette.module.d.ts +3 -0
  54. package/dist/palette/palette.module.d.ts.map +1 -0
  55. package/dist/plugins/font/font.plugin.d.ts +1 -1
  56. package/dist/plugins/font/font.plugin.d.ts.map +1 -1
  57. package/dist/variant/index.d.ts +3 -0
  58. package/dist/variant/index.d.ts.map +1 -0
  59. package/dist/variant/variant.d.ts +29 -0
  60. package/dist/variant/variant.d.ts.map +1 -0
  61. package/dist/variant/variants/expressive.variant.d.ts +2 -0
  62. package/dist/variant/variants/expressive.variant.d.ts.map +1 -0
  63. package/dist/variant/variants/fidelity.variant.d.ts.map +1 -0
  64. package/dist/variant/variants/index.d.ts.map +1 -0
  65. package/dist/variant/variants/neutral.variant.d.ts.map +1 -0
  66. package/dist/variant/variants/tonal-spot.variant.d.ts.map +1 -0
  67. package/dist/variant/variants/vibrant.variant.d.ts.map +1 -0
  68. package/package.json +1 -1
  69. package/src/API.ts +12 -5
  70. package/src/app.container.ts +22 -11
  71. package/src/bootstrap.ts +1 -1
  72. package/src/color/color.api.ts +168 -47
  73. package/src/color/color.manager.ts +38 -181
  74. package/src/color/color.ts +291 -0
  75. package/src/color/color.utils.ts +48 -3
  76. package/src/color/default-color.ts +395 -396
  77. package/src/color/index.ts +1 -1
  78. package/src/config/config.interface.ts +5 -4
  79. package/src/context/context.module.ts +7 -0
  80. package/src/context/context.ts +169 -0
  81. package/src/context/index.ts +2 -0
  82. package/src/index.ts +6 -4
  83. package/src/loader/loader.ts +14 -23
  84. package/src/material-color-utilities/dynamic_color.ts +25 -34
  85. package/src/material-color-utilities/toneDeltaPair.ts +44 -41
  86. package/src/palette/index.ts +3 -0
  87. package/src/palette/palette.api.ts +43 -0
  88. package/src/palette/palette.manager.ts +74 -0
  89. package/src/palette/palette.module.ts +9 -0
  90. package/src/palette/palette.ts +207 -0
  91. package/src/plugins/font/font.plugin.ts +1 -1
  92. package/src/variant/index.ts +2 -0
  93. package/src/variant/variant.ts +81 -0
  94. package/src/{theme → variant}/variants/expressive.variant.ts +31 -29
  95. package/src/variant/variants/fidelity.variant.ts +46 -0
  96. package/src/{theme → variant}/variants/neutral.variant.ts +18 -18
  97. package/src/variant/variants/tonal-spot.variant.ts +35 -0
  98. package/src/{theme → variant}/variants/vibrant.variant.ts +21 -22
  99. package/dist/color/configurable-color.d.ts +0 -31
  100. package/dist/color/configurable-color.d.ts.map +0 -1
  101. package/dist/define-config-BasMdCqD.js +0 -430
  102. package/dist/define-config-CKSsLMnc.cjs +0 -429
  103. package/dist/theme/index.d.ts +0 -8
  104. package/dist/theme/index.d.ts.map +0 -1
  105. package/dist/theme/scheme.d.ts +0 -20
  106. package/dist/theme/scheme.d.ts.map +0 -1
  107. package/dist/theme/scheme.manager.d.ts +0 -31
  108. package/dist/theme/scheme.manager.d.ts.map +0 -1
  109. package/dist/theme/theme.api.d.ts +0 -24
  110. package/dist/theme/theme.api.d.ts.map +0 -1
  111. package/dist/theme/theme.module.d.ts +0 -3
  112. package/dist/theme/theme.module.d.ts.map +0 -1
  113. package/dist/theme/variant.d.ts +0 -36
  114. package/dist/theme/variant.d.ts.map +0 -1
  115. package/dist/theme/variant.manager.d.ts +0 -14
  116. package/dist/theme/variant.manager.d.ts.map +0 -1
  117. package/dist/theme/variants/expressive.variant.d.ts +0 -3
  118. package/dist/theme/variants/expressive.variant.d.ts.map +0 -1
  119. package/dist/theme/variants/fidelity.variant.d.ts.map +0 -1
  120. package/dist/theme/variants/index.d.ts.map +0 -1
  121. package/dist/theme/variants/neutral.variant.d.ts.map +0 -1
  122. package/dist/theme/variants/tonal-spot.variant.d.ts.map +0 -1
  123. package/dist/theme/variants/vibrant.variant.d.ts.map +0 -1
  124. package/src/color/configurable-color.ts +0 -67
  125. package/src/theme/index.ts +0 -7
  126. package/src/theme/scheme.manager.ts +0 -100
  127. package/src/theme/scheme.ts +0 -66
  128. package/src/theme/theme.api.ts +0 -82
  129. package/src/theme/theme.module.ts +0 -11
  130. package/src/theme/variant.manager.ts +0 -58
  131. package/src/theme/variant.ts +0 -53
  132. package/src/theme/variants/fidelity.variant.ts +0 -38
  133. package/src/theme/variants/tonal-spot.variant.ts +0 -35
  134. /package/dist/{theme → variant}/variants/fidelity.variant.d.ts +0 -0
  135. /package/dist/{theme → variant}/variants/index.d.ts +0 -0
  136. /package/dist/{theme → variant}/variants/neutral.variant.d.ts +0 -0
  137. /package/dist/{theme → variant}/variants/tonal-spot.variant.d.ts +0 -0
  138. /package/dist/{theme → variant}/variants/vibrant.variant.d.ts +0 -0
  139. /package/src/{theme → variant}/variants/index.ts +0 -0
@@ -0,0 +1,291 @@
1
+ import {
2
+ argbFromHex,
3
+ clampDouble,
4
+ Contrast,
5
+ hexFromArgb,
6
+ } from '@material/material-color-utilities';
7
+ import { ContrastCurve, DynamicColor } from '../material-color-utilities';
8
+ import { Hct } from '../material-color-utilities/htc';
9
+ import { ColorManager } from './color.manager';
10
+ import { Palette } from '../palette/palette';
11
+ import { Context } from 'src/context';
12
+
13
+ export type ColorOptions =
14
+ | FromPaletteOptions
15
+ | {
16
+ hex: string;
17
+ }
18
+ | {
19
+ alias: string;
20
+ };
21
+
22
+ function argbToRgb(argb: number): { r: number; g: number; b: number } {
23
+ return {
24
+ r: (argb >> 16) & 0xff,
25
+ g: (argb >> 8) & 0xff,
26
+ b: argb & 0xff,
27
+ };
28
+ }
29
+
30
+ export function getInitialToneFromBackground(background?: Color): number {
31
+ if (background === undefined) {
32
+ return 50;
33
+ }
34
+ return background.getTone();
35
+ }
36
+
37
+ export abstract class Color {
38
+ abstract getHct(): Hct;
39
+
40
+ protected constructor(public readonly name: string) {}
41
+
42
+ getHex(): string {
43
+ return hexFromArgb(this.getArgb());
44
+ }
45
+
46
+ getArgb() {
47
+ return this.getHct().toInt();
48
+ }
49
+
50
+ getRgb() {
51
+ return argbToRgb(this.getArgb());
52
+ }
53
+ getTone(): number {
54
+ return this.getHct().tone;
55
+ }
56
+ }
57
+
58
+ export class ColorAlias extends Color {
59
+ getHct(): Hct {
60
+ return this.colorService.get(this.as).getHct();
61
+ }
62
+
63
+ constructor(
64
+ name: string,
65
+ public as: string,
66
+ public colorService: ColorManager,
67
+ ) {
68
+ super(name);
69
+ }
70
+
71
+ color() {
72
+ return this.colorService.get(this.as) as ColorFromPalette;
73
+ }
74
+ }
75
+
76
+ export class ColorFromHex extends Color {
77
+ getHct(): Hct {
78
+ return Hct.fromInt(argbFromHex(this.getHex()));
79
+ }
80
+
81
+ override getHex(): string {
82
+ return this._hex;
83
+ }
84
+
85
+ setHex(hex: string) {
86
+ this._hex = hex;
87
+ }
88
+
89
+ constructor(
90
+ name: string,
91
+ private _hex: string,
92
+ ) {
93
+ super(name);
94
+ this._hex = _hex;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * @param name The name of the dynamic color. Defaults to empty.
100
+ * @param palette Function that provides a TonalPalette given DynamicScheme. A
101
+ * TonalPalette is defined by a hue and chroma, so this replaces the need to
102
+ * specify hue/chroma. By providing a tonal palette, when contrast
103
+ * adjustments are made, intended chroma can be preserved.
104
+ * @param tone Function that provides a tone given DynamicScheme. When not
105
+ * provided, the tone is same as the background tone or 50, when no
106
+ * background is provided.
107
+ * @param chromaMultiplier A factor that multiplies the chroma for this color.
108
+ * Default to 1.
109
+ * @param isBackground Whether this dynamic color is a background, with some
110
+ * other color as the foreground. Defaults to false.
111
+ * @param background The background of the dynamic color (as a function of a
112
+ * `DynamicScheme`), if it exists.
113
+ * @param secondBackground A second background of the dynamic color (as a
114
+ * function of a `DynamicScheme`), if it exists.
115
+ * @param contrastCurve A `ContrastCurve` object specifying how its contrast
116
+ * against its background should behave in various contrast levels options.
117
+ * Must used together with `background`. When not provided or resolved as
118
+ * undefined, the contrast curve is calculated based on other constraints.
119
+ * @param adjustTone A `AdjustTone` object specifying a tone delta
120
+ * constraint between two colors. One of them must be the color being
121
+ * constructed. When not provided or resolved as undefined, the tone is
122
+ * calculated based on other constraints.
123
+ */
124
+ export type FromPaletteOptions = {
125
+ palette: () => Palette;
126
+ tone?: () => number;
127
+ chromaMultiplier?: () => number | undefined;
128
+ isBackground?: boolean;
129
+ background?: () => Color | undefined;
130
+ secondBackground?: () => Color | undefined;
131
+ contrastCurve?: () => ContrastCurve | undefined;
132
+ adjustTone?: () => AdjustTone | undefined;
133
+ };
134
+
135
+ export type FromPalette = {
136
+ palette: Palette;
137
+ tone: number;
138
+ chromaMultiplier: number;
139
+ isBackground?: boolean;
140
+ background?: Color;
141
+ secondBackground?: Color;
142
+ contrastCurve?: ContrastCurve;
143
+ adjustTone?: AdjustTone;
144
+ };
145
+
146
+ export type AdjustTone = (args: { context: Context; color: Color }) => number;
147
+
148
+ export class ColorFromPalette extends Color {
149
+ get options(): FromPalette {
150
+ const options = {
151
+ ...this._options,
152
+ palette: this._options.palette(),
153
+ tone: this._options.tone?.(),
154
+ chromaMultiplier: this._options.chromaMultiplier?.(),
155
+ background: this._options.background?.(),
156
+ secondBackground: this._options.secondBackground?.(),
157
+ contrastCurve: this._options.contrastCurve?.(),
158
+ adjustTone: this._options.adjustTone?.(),
159
+ };
160
+
161
+ return {
162
+ ...options,
163
+ chromaMultiplier: options.chromaMultiplier ?? 1,
164
+ tone: options.tone ?? getInitialToneFromBackground(options.background),
165
+ };
166
+ }
167
+
168
+ constructor(
169
+ name: string,
170
+ private _options: FromPaletteOptions,
171
+ private context: Context,
172
+ ) {
173
+ super(name);
174
+ this.validateOption();
175
+ }
176
+
177
+ update(args: Partial<ColorOptions>) {
178
+ this._options = { ...this._options, ...args };
179
+ this.validateOption();
180
+ }
181
+
182
+ validateOption() {
183
+ const option = this._options;
184
+ if ('palette' in option) {
185
+ if (!option.background && option.secondBackground) {
186
+ throw new Error(
187
+ `Color ${this.name} has secondBackground ` +
188
+ `defined, but background is not defined.`,
189
+ );
190
+ }
191
+ if (!option.background && option.contrastCurve) {
192
+ throw new Error(
193
+ `Color ${this.name} has contrastCurve ` +
194
+ `defined, but background is not defined.`,
195
+ );
196
+ }
197
+ if (option.background && !option.contrastCurve) {
198
+ throw new Error(
199
+ `Color ${this.name} has background ` +
200
+ `defined, but contrastCurve is not defined.`,
201
+ );
202
+ }
203
+ }
204
+ }
205
+
206
+ getHct(): Hct {
207
+ const option = this.options;
208
+
209
+ const palette = option.palette;
210
+ const tone = this.getTone();
211
+ const hue = palette.hue;
212
+ const chroma = palette.chroma * option.chromaMultiplier;
213
+ return Hct.from(hue, chroma, tone);
214
+ }
215
+
216
+ override getTone(): number {
217
+ const context = this.context;
218
+
219
+ const options = this.options;
220
+
221
+ const adjustTone = options.adjustTone;
222
+
223
+ // Case 0: tone delta constraint.
224
+ if (adjustTone) {
225
+ return adjustTone({ context, color: this });
226
+ } else {
227
+ // Case 1: No tone delta pair; just solve for itself.
228
+ let answer = options.tone;
229
+ if (!options.background || !options.contrastCurve) {
230
+ return answer; // No adjustment for colors with no background.
231
+ }
232
+ const bgTone = options.background.getTone();
233
+ const desiredRatio = options.contrastCurve.get(context.contrastLevel);
234
+ // Recalculate the tone from desired contrast ratio if the current
235
+ // contrast ratio is not enough or desired contrast level is decreasing
236
+ // (<0).
237
+ answer =
238
+ Contrast.ratioOfTones(bgTone, answer) >= desiredRatio &&
239
+ context.contrastLevel >= 0
240
+ ? answer
241
+ : DynamicColor.foregroundTone(bgTone, desiredRatio);
242
+ // This can avoid the awkward tones for background colors including the
243
+ // access fixed colors. Accent fixed dim colors should not be adjusted.
244
+ if (options.isBackground && !this.name.endsWith('_fixed_dim')) {
245
+ if (answer >= 57) {
246
+ answer = clampDouble(65, 100, answer);
247
+ } else {
248
+ answer = clampDouble(0, 49, answer);
249
+ }
250
+ }
251
+ if (!options.secondBackground) {
252
+ return answer;
253
+ }
254
+ // Case 2: Adjust for dual backgrounds.
255
+ const [bg1, bg2] = [options.background, options.secondBackground];
256
+ const [bgTone1, bgTone2] = [bg1.getTone(), bg2.getTone()];
257
+ const [upper, lower] = [
258
+ Math.max(bgTone1, bgTone2),
259
+ Math.min(bgTone1, bgTone2),
260
+ ];
261
+ if (
262
+ Contrast.ratioOfTones(upper, answer) >= desiredRatio &&
263
+ Contrast.ratioOfTones(lower, answer) >= desiredRatio
264
+ ) {
265
+ return answer;
266
+ }
267
+ // The darkest light tone that satisfies the desired ratio,
268
+ // or -1 if such ratio cannot be reached.
269
+ const lightOption = Contrast.lighter(upper, desiredRatio);
270
+
271
+ // The lightest dark tone that satisfies the desired ratio,
272
+ // or -1 if such ratio cannot be reached.
273
+ const darkOption = Contrast.darker(lower, desiredRatio);
274
+ // Tones suitable for the foreground.
275
+ const availables = [];
276
+ if (lightOption !== -1) availables.push(lightOption);
277
+ if (darkOption !== -1) availables.push(darkOption);
278
+
279
+ const prefersLight =
280
+ DynamicColor.tonePrefersLightForeground(bgTone1) ||
281
+ DynamicColor.tonePrefersLightForeground(bgTone2);
282
+ if (prefersLight) {
283
+ return lightOption < 0 ? 100 : lightOption;
284
+ }
285
+ if (availables.length === 1) {
286
+ return availables[0];
287
+ }
288
+ return darkOption < 0 ? 0 : darkOption;
289
+ }
290
+ }
291
+ }
@@ -1,6 +1,7 @@
1
- import { clampDouble, TonalPalette } from '@material/material-color-utilities';
1
+ import { clampDouble, Contrast } from '@material/material-color-utilities';
2
2
  import { Hct } from '../material-color-utilities/htc';
3
3
  import { ContrastCurve } from '../material-color-utilities/contrastCurve';
4
+ import { Palette } from '../palette/palette';
4
5
 
5
6
  export type DynamicColorKey =
6
7
  | 'background'
@@ -79,7 +80,7 @@ export function getCurve(defaultContrast: number): ContrastCurve {
79
80
  }
80
81
 
81
82
  export function tMaxC(
82
- palette: TonalPalette,
83
+ palette: Palette,
83
84
  lowerBound = 0,
84
85
  upperBound = 100,
85
86
  chromaMultiplier = 1,
@@ -94,7 +95,7 @@ export function tMaxC(
94
95
  }
95
96
 
96
97
  export function tMinC(
97
- palette: TonalPalette,
98
+ palette: Palette,
98
99
  lowerBound = 0,
99
100
  upperBound = 100,
100
101
  ): number {
@@ -124,3 +125,47 @@ export function findBestToneForChroma(
124
125
 
125
126
  return answer;
126
127
  }
128
+
129
+ /**
130
+ * Calcule le pourcentage des tons à ajuster pour atteindre un ratio de contraste.
131
+ *
132
+ * @param toneA Le premier ton (par exemple, tone de surface).
133
+ * @param toneB Le ton cible à ajuster.
134
+ * @param desiredRatio Le ratio de contraste requis (ex : 3, 4.5, 7).
135
+ * @returns Un pourcentage (entre 0 et 100) indiquant l'effort nécessaire :
136
+ * - 0% si `toneB` est au bon ratio.
137
+ * - Un pourcentage positif ou négatif en fonction de la distance à ajuster.
138
+ */
139
+ export function calculateToneAdjustmentPercentage(
140
+ toneA: number,
141
+ toneB: number,
142
+ desiredRatio: number,
143
+ ): number {
144
+ // Vérification du ratio actuel
145
+ const currentRatio = Contrast.ratioOfTones(toneA, toneB);
146
+
147
+ // Si le ratio est déjà atteint, inutile de changer
148
+ if (currentRatio >= desiredRatio) {
149
+ return 0;
150
+ }
151
+
152
+ // Calcul pour déterminer le ton minimal plus clair qui respecte le ratio
153
+ const lighterTone = Contrast.lighter(toneA, desiredRatio);
154
+
155
+ // Calcul pour déterminer le ton maximal plus sombre qui respecte le ratio
156
+ const darkerTone = Contrast.darker(toneA, desiredRatio);
157
+
158
+ // Vérifie quelle direction est atteignable et compare à toneB
159
+ if (lighterTone !== -1 && toneB < lighterTone) {
160
+ const percentageToAdjust = (toneB - lighterTone) / (toneA - lighterTone);
161
+ return clampDouble(0, 1, percentageToAdjust);
162
+ }
163
+
164
+ if (darkerTone !== -1 && toneB > darkerTone) {
165
+ const percentageToAdjust = (toneB - darkerTone) / (toneA - darkerTone);
166
+ return clampDouble(0, 1, percentageToAdjust);
167
+ }
168
+
169
+ // Si aucun ajustement n'est possible ou nécessaire
170
+ return 0;
171
+ }