@digdir/designsystemet 0.1.0-alpha.17 → 0.1.0-alpha.19

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 (91) hide show
  1. package/LICENSE +7 -0
  2. package/dist/bin/designsystemet.js +24 -28
  3. package/dist/src/colors/colorUtils.js +223 -315
  4. package/dist/src/colors/index.js +3 -3
  5. package/dist/src/colors/themeUtils.js +227 -319
  6. package/dist/src/colors/types.js +0 -1
  7. package/dist/src/init/createTokensPackage.js +223 -201
  8. package/dist/src/init/generateMetadataJson.js +19 -14
  9. package/dist/src/init/generateThemesJson.js +49 -40
  10. package/dist/src/init/index.js +7 -4
  11. package/dist/src/init/nextStepsMarkdown.js +15 -13
  12. package/dist/src/init/template/prettier.config.js +5 -7
  13. package/dist/src/init/template/template-files/package.json +1 -0
  14. package/dist/src/init/utils.js +11 -7
  15. package/dist/src/migrations/beta-to-v1.js +342 -339
  16. package/dist/src/migrations/codemods/css/plugins.js +40 -36
  17. package/dist/src/migrations/codemods/css/run.js +15 -20
  18. package/dist/src/migrations/codemods/jsx/classname-prefix.js +57 -63
  19. package/dist/src/migrations/codemods/jsx/run.js +17 -19
  20. package/dist/src/migrations/index.js +6 -3
  21. package/dist/src/migrations/react-beta-to-v1.js +4 -3
  22. package/dist/src/tokens/actions.js +25 -23
  23. package/dist/src/tokens/build.js +65 -51
  24. package/dist/src/tokens/configs.js +188 -223
  25. package/dist/src/tokens/formats/css.js +143 -150
  26. package/dist/src/tokens/formats/js-tokens.js +27 -26
  27. package/dist/src/tokens/transformers.js +39 -41
  28. package/dist/src/tokens/utils/noCase.js +25 -25
  29. package/dist/src/tokens/utils/permutateThemes.js +50 -64
  30. package/dist/src/tokens/utils/utils.js +12 -25
  31. package/package.json +8 -3
  32. package/dist/src/test/a.css +0 -39
  33. package/dist/src/test/jsx-test.js +0 -12
  34. package/dist/types/bin/designsystemet.d.ts +0 -3
  35. package/dist/types/bin/designsystemet.d.ts.map +0 -1
  36. package/dist/types/src/colors/colorUtils.d.ts +0 -126
  37. package/dist/types/src/colors/colorUtils.d.ts.map +0 -1
  38. package/dist/types/src/colors/index.d.ts +0 -4
  39. package/dist/types/src/colors/index.d.ts.map +0 -1
  40. package/dist/types/src/colors/themeUtils.d.ts +0 -102
  41. package/dist/types/src/colors/themeUtils.d.ts.map +0 -1
  42. package/dist/types/src/colors/types.d.ts +0 -16
  43. package/dist/types/src/colors/types.d.ts.map +0 -1
  44. package/dist/types/src/init/createTokensPackage.d.ts +0 -5
  45. package/dist/types/src/init/createTokensPackage.d.ts.map +0 -1
  46. package/dist/types/src/init/generateMetadataJson.d.ts +0 -6
  47. package/dist/types/src/init/generateMetadataJson.d.ts.map +0 -1
  48. package/dist/types/src/init/generateThemesJson.d.ts +0 -3
  49. package/dist/types/src/init/generateThemesJson.d.ts.map +0 -1
  50. package/dist/types/src/init/index.d.ts +0 -3
  51. package/dist/types/src/init/index.d.ts.map +0 -1
  52. package/dist/types/src/init/nextStepsMarkdown.d.ts +0 -3
  53. package/dist/types/src/init/nextStepsMarkdown.d.ts.map +0 -1
  54. package/dist/types/src/init/template/prettier.config.d.mts +0 -9
  55. package/dist/types/src/init/template/prettier.config.d.mts.map +0 -1
  56. package/dist/types/src/init/utils.d.ts +0 -4
  57. package/dist/types/src/init/utils.d.ts.map +0 -1
  58. package/dist/types/src/migrations/beta-to-v1.d.ts +0 -3
  59. package/dist/types/src/migrations/beta-to-v1.d.ts.map +0 -1
  60. package/dist/types/src/migrations/codemods/css/plugins.d.ts +0 -6
  61. package/dist/types/src/migrations/codemods/css/plugins.d.ts.map +0 -1
  62. package/dist/types/src/migrations/codemods/css/run.d.ts +0 -8
  63. package/dist/types/src/migrations/codemods/css/run.d.ts.map +0 -1
  64. package/dist/types/src/migrations/codemods/jsx/classname-prefix.d.ts +0 -10
  65. package/dist/types/src/migrations/codemods/jsx/classname-prefix.d.ts.map +0 -1
  66. package/dist/types/src/migrations/codemods/jsx/run.d.ts +0 -7
  67. package/dist/types/src/migrations/codemods/jsx/run.d.ts.map +0 -1
  68. package/dist/types/src/migrations/index.d.ts +0 -6
  69. package/dist/types/src/migrations/index.d.ts.map +0 -1
  70. package/dist/types/src/migrations/react-beta-to-v1.d.ts +0 -3
  71. package/dist/types/src/migrations/react-beta-to-v1.d.ts.map +0 -1
  72. package/dist/types/src/test/jsx-test.d.ts +0 -4
  73. package/dist/types/src/test/jsx-test.d.ts.map +0 -1
  74. package/dist/types/src/tokens/actions.d.ts +0 -6
  75. package/dist/types/src/tokens/actions.d.ts.map +0 -1
  76. package/dist/types/src/tokens/build.d.ts +0 -11
  77. package/dist/types/src/tokens/build.d.ts.map +0 -1
  78. package/dist/types/src/tokens/configs.d.ts +0 -31
  79. package/dist/types/src/tokens/configs.d.ts.map +0 -1
  80. package/dist/types/src/tokens/formats/css.d.ts +0 -5
  81. package/dist/types/src/tokens/formats/css.d.ts.map +0 -1
  82. package/dist/types/src/tokens/formats/js-tokens.d.ts +0 -6
  83. package/dist/types/src/tokens/formats/js-tokens.d.ts.map +0 -1
  84. package/dist/types/src/tokens/transformers.d.ts +0 -5
  85. package/dist/types/src/tokens/transformers.d.ts.map +0 -1
  86. package/dist/types/src/tokens/utils/noCase.d.ts +0 -11
  87. package/dist/types/src/tokens/utils/noCase.d.ts.map +0 -1
  88. package/dist/types/src/tokens/utils/permutateThemes.d.ts +0 -17
  89. package/dist/types/src/tokens/utils/permutateThemes.d.ts.map +0 -1
  90. package/dist/types/src/tokens/utils/utils.d.ts +0 -24
  91. package/dist/types/src/tokens/utils/utils.d.ts.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2024 Digitaliseringsdirektoratet (Digdir)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -4,35 +4,31 @@ import chalk from "chalk";
4
4
  import migrations from "../src/migrations/index.js";
5
5
  import { run } from "../src/tokens/build.js";
6
6
  import { makeInitCommand } from "../src/init/index.js";
7
- program.name('Designsystemet').description('CLI for working with Designsystemet');
8
- program.command('tokens').showHelpAfterError().description('run Designsystemet token builder').option('-t, --tokens [string]', `Path to ${chalk.blue('design-tokens')}`, './design-tokens').option('-o, --out [string]', `Output directory for built ${chalk.blue('design-tokens')}`, './dist/tokens').option('-p, --preview', 'Generate preview token.ts files', false).action((opts)=>{
9
- const tokens = typeof opts.tokens === 'string' ? opts.tokens : './design-tokens';
10
- const out = typeof opts.out === 'string' ? opts.out : './dist/tokens';
11
- const preview = opts.preview;
12
- console.log(`Bulding tokens in ${chalk.green(tokens)}`);
13
- return run({
14
- tokens,
15
- out,
16
- preview
17
- });
7
+ program.name("Designsystemet").description("CLI for working with Designsystemet");
8
+ program.command("tokens").showHelpAfterError().description("run Designsystemet token builder").option("-t, --tokens [string]", `Path to ${chalk.blue("design-tokens")}`, "./design-tokens").option("-o, --out [string]", `Output directory for built ${chalk.blue("design-tokens")}`, "./dist/tokens").option("-p, --preview", "Generate preview token.ts files", false).action((opts) => {
9
+ const tokens = typeof opts.tokens === "string" ? opts.tokens : "./design-tokens";
10
+ const out = typeof opts.out === "string" ? opts.out : "./dist/tokens";
11
+ const preview = opts.preview;
12
+ console.log(`Bulding tokens in ${chalk.green(tokens)}`);
13
+ return run({ tokens, out, preview });
18
14
  });
19
- program.command('migrate').showHelpAfterError().description('run a Designsystemet migration').addArgument(new Argument('[migration]', 'Available migrations').choices(Object.keys(migrations))).option('-l --list', 'List available migrations').option('-g --glob <glob>', 'Glob for files upon which to apply the migration', './**/*.(tsx|css)').action((migrationKey, opts)=>{
20
- const { glob, list } = opts;
21
- if (list) {
22
- Object.keys(migrations).forEach((key)=>{
23
- console.log(key);
24
- });
25
- } else if (migrationKey) {
26
- const migration = migrations[migrationKey];
27
- if (!migration) {
28
- console.error('Migration not found!');
29
- throw 'Aborting';
30
- }
31
- console.log(`Applying migration ${chalk.blue(migrationKey)} with glob: ${chalk.green(glob)}`);
32
- migration?.(glob).then(()=>console.log(`Migration ${chalk.blue(migrationKey)} finished`)).catch((error)=>console.log(error));
33
- } else {
34
- console.log('Migrate: please specify a migration name or --list');
15
+ program.command("migrate").showHelpAfterError().description("run a Designsystemet migration").addArgument(new Argument("[migration]", "Available migrations").choices(Object.keys(migrations))).option("-l --list", "List available migrations").option("-g --glob <glob>", "Glob for files upon which to apply the migration", "./**/*.(tsx|css)").action((migrationKey, opts) => {
16
+ const { glob, list } = opts;
17
+ if (list) {
18
+ Object.keys(migrations).forEach((key) => {
19
+ console.log(key);
20
+ });
21
+ } else if (migrationKey) {
22
+ const migration = migrations[migrationKey];
23
+ if (!migration) {
24
+ console.error("Migration not found!");
25
+ throw "Aborting";
35
26
  }
27
+ console.log(`Applying migration ${chalk.blue(migrationKey)} with glob: ${chalk.green(glob)}`);
28
+ migration?.(glob).then(() => console.log(`Migration ${chalk.blue(migrationKey)} finished`)).catch((error) => console.log(error));
29
+ } else {
30
+ console.log("Migrate: please specify a migration name or --list");
31
+ }
36
32
  });
37
- program.addCommand(makeInitCommand(new Command('init')));
33
+ program.addCommand(makeInitCommand(new Command("init")));
38
34
  await program.parseAsync(process.argv);
@@ -1,322 +1,230 @@
1
1
  import { Hsluv } from "hsluv";
2
2
  import chroma from "chroma-js";
3
3
  import { APCAcontrast, sRGBtoY } from "apca-w3";
4
- /**
5
- * Converts a HEX color '#xxxxxx' into a CSS HSL string 'hsl(x,x,x)'
6
- *
7
- * @param hex A hex color string
8
- * @param valuesOnly If true, only the values are returned
9
- * @returns A CSS HSL string
10
- */ export const hexToCssHsl = (hex, valuesOnly = false)=>{
11
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
12
- let r = 0;
13
- let g = 0;
14
- let b = 0;
15
- let cssString = '';
16
- if (result) {
17
- r = parseInt(result[1], 16);
18
- g = parseInt(result[2], 16);
19
- b = parseInt(result[3], 16);
20
- }
21
- r /= 255, g /= 255, b /= 255;
22
- const max = Math.max(r, g, b), min = Math.min(r, g, b);
23
- let h, s, l = (max + min) / 2;
24
- if (max == min) {
25
- h = s = 0; // achromatic
26
- } else {
27
- const d = max - min;
28
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
29
- switch(max){
30
- case r:
31
- h = (g - b) / d + (g < b ? 6 : 0);
32
- break;
33
- case g:
34
- h = (b - r) / d + 2;
35
- break;
36
- case b:
37
- h = (r - g) / d + 4;
38
- break;
39
- }
40
- }
41
- h = Math.round(h ? h * 360 : 0);
42
- s = Math.round(s * 100);
43
- l = Math.round(l * 100);
44
- cssString = h + ',' + s + '%,' + l + '%';
45
- cssString = !valuesOnly ? 'hsl(' + cssString + ')' : cssString;
46
- return cssString;
47
- };
48
- /**
49
- * Converts a HEX string '#xxxxxx' into an array of HSL values '[h,s,l]'
50
- *
51
- * @param H A Hex color string
52
- * @returns HSL values in an array
53
- */ export const hexToHSL = (H)=>{
54
- // Convert hex to RGB first
55
- let r = 0, g = 0, b = 0;
56
- if (H.length == 4) {
57
- r = parseInt('0x' + H[1] + H[1]);
58
- g = parseInt('0x' + H[2] + H[2]);
59
- b = parseInt('0x' + H[3] + H[3]);
60
- } else if (H.length == 7) {
61
- r = parseInt('0x' + H[1] + H[2]);
62
- g = parseInt('0x' + H[3] + H[4]);
63
- b = parseInt('0x' + H[5] + H[6]);
64
- }
65
- // Then to HSL
66
- r /= 255;
67
- g /= 255;
68
- b /= 255;
69
- let h = 0, s = 0, l = 0;
70
- const cmin = Math.min(r, g, b), cmax = Math.max(r, g, b), delta = cmax - cmin;
71
- if (delta == 0) h = 0;
72
- else if (cmax == r) h = (g - b) / delta % 6;
73
- else if (cmax == g) h = (b - r) / delta + 2;
74
- else h = (r - g) / delta + 4;
75
- h = Math.round(h * 60);
76
- if (h < 0) h += 360;
77
- l = (cmax + cmin) / 2;
78
- s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
79
- s = +(s * 100).toFixed(1);
80
- l = +(l * 100).toFixed(1);
81
- return [
82
- h,
83
- s,
84
- l
85
- ];
86
- };
87
- /**
88
- * Converts a HEX color '#xxxxxx' into an array of HSLuv values '[h,s,l]'
89
- *
90
- * @param hex A hex color string
91
- * @returns
92
- */ export const hexToHsluv = (hex)=>{
93
- const conv = new Hsluv();
94
- conv.hex = hex;
95
- conv.hexToHsluv();
96
- return [
97
- conv.hsluv_h,
98
- conv.hsluv_s,
99
- conv.hsluv_l
100
- ];
101
- };
102
- /**
103
- * Converts a HSL number array '[h,s,l]' into HSL CSS string 'hsl(x,x,x)'
104
- *
105
- * @param HSL A HSL number array '[h,s,l]'
106
- * @returns A hex color string
107
- */ export const hslArrToCss = (HSL)=>{
108
- return 'hsl(' + HSL[0] + ',' + HSL[1] + '%,' + HSL[2] + '%)';
109
- };
110
- /**
111
- * Converts a HSL CSS string 'hsl(x,x,x)' into an array of HSL values '[h,s,l]'
112
- *
113
- * @param h The HSL hue
114
- * @param s The HSL saturation
115
- * @param l The HSL lightness
116
- * @returns HEX color string
117
- */ export const HSLToHex = (h, s, l)=>{
118
- s /= 100;
119
- l /= 100;
120
- let r = 0, g = 0, b = 0;
121
- const c = (1 - Math.abs(2 * l - 1)) * s, x = c * (1 - Math.abs(h / 60 % 2 - 1)), m = l - c / 2;
122
- if (0 <= h && h < 60) {
123
- r = c;
124
- g = x;
125
- b = 0;
126
- } else if (60 <= h && h < 120) {
127
- r = x;
128
- g = c;
129
- b = 0;
130
- } else if (120 <= h && h < 180) {
131
- r = 0;
132
- g = c;
133
- b = x;
134
- } else if (180 <= h && h < 240) {
135
- r = 0;
136
- g = x;
137
- b = c;
138
- } else if (240 <= h && h < 300) {
139
- r = x;
140
- g = 0;
141
- b = c;
142
- } else if (300 <= h && h < 360) {
143
- r = c;
144
- g = 0;
145
- b = x;
146
- }
147
- // Having obtained RGB, convert channels to hex
148
- r = parseInt(Math.round((r + m) * 255).toString(16), 16);
149
- g = parseInt(Math.round((g + m) * 255).toString(16), 16);
150
- b = parseInt(Math.round((b + m) * 255).toString(16), 16);
151
- // Prepend 0s, if necessary
152
- if (r.toString().length == 1) r = parseInt('0' + r.toString(), 10);
153
- if (g.toString().length == 1) g = parseInt('0' + g.toString(), 10);
154
- if (b.toString().length == 1) b = parseInt('0' + b.toString(), 10);
155
- return '#' + r + g + b;
156
- };
157
- /**
158
- * Converts a HEX color '#xxxxxx' into an array of RGB values '[R, G, B]'
159
- *
160
- * @param hex A hex color string
161
- * @returns RGB values in an array
162
- */ export const hexToRgb = (hex)=>{
163
- const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
164
- hex = hex.replace(shorthandRegex, function(m, r, g, b) {
165
- return r + r + g + g + b + b;
166
- });
167
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
168
- return result ? {
169
- r: parseInt(result[1], 16),
170
- g: parseInt(result[2], 16),
171
- b: parseInt(result[3], 16)
172
- } : null;
173
- };
174
- /**
175
- * Get the luminance of an RGB color
176
- *
177
- * @param r RGB red value
178
- * @param G RGB green value
179
- * @param b RGB blue value
180
- * @returns
181
- */ export const luminanceFromRgb = (r, g, b)=>{
182
- const a = [
183
- Number(r),
184
- Number(g),
185
- Number(b)
186
- ].map(function(v) {
187
- v /= 255;
188
- return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
189
- });
190
- return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
191
- };
192
- /**
193
- * Get the luminance of a HEX color
194
- *
195
- * @param hex A hex color string
196
- * @returns
197
- */ export const luminanceFromHex = (hex)=>{
198
- const rgb = hexToRgb(hex);
199
- if (rgb) {
200
- const r = rgb.r.toString();
201
- const g = rgb.g.toString();
202
- const b = rgb.b.toString();
203
- return luminanceFromRgb(r, g, b);
204
- }
205
- return 2;
206
- };
207
- /**
208
- * Get the contrast ratio between two luminance values
209
- *
210
- * @param lum1 The first luminance value
211
- * @param lum2 The second luminance value
212
- * @returns
213
- */ export const getRatioFromLum = (lum1, lum2)=>{
214
- if (lum1 !== null && lum2 !== null) {
215
- return (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05);
216
- } else {
217
- return -1;
218
- }
219
- };
220
- /**
221
- * Get the HSL lightness from a HEX color
222
- *
223
- * @param hex A hex color string
224
- * @returns
225
- */ export const getHslLightessFromHex = (hex)=>{
226
- return chroma(hex).hsl()[2];
227
- };
228
- export const getHslSaturationFromHex = (hex)=>{
229
- return chroma(hex).hsl()[1];
230
- };
231
- /**
232
- * Get the HSLuv lightness from a HEX color
233
- *
234
- * @param hex A hex color string
235
- * @returns
236
- */ export const getLightnessFromHex = (hex)=>{
237
- const conv = new Hsluv();
238
- conv.hex = hex;
239
- conv.hexToHsluv();
240
- return Number(conv.hsluv_l.toFixed(0));
241
- };
242
- /**
243
- * Get the contrast ratio between two HEX colors
244
- *
245
- * @param {CssColor} color1 The first color
246
- * @param {CssColor} color2 The second color
247
- * @returns
248
- */ export const getContrastFromHex = (color1, color2)=>{
249
- const lum1 = luminanceFromHex(color1);
250
- const lum2 = luminanceFromHex(color2);
251
- if (lum1 !== null && lum2 !== null) {
252
- return getRatioFromLum(lum1, lum2);
4
+ const hexToCssHsl = (hex, valuesOnly = false) => {
5
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
6
+ let r = 0;
7
+ let g = 0;
8
+ let b = 0;
9
+ let cssString = "";
10
+ if (result) {
11
+ r = parseInt(result[1], 16);
12
+ g = parseInt(result[2], 16);
13
+ b = parseInt(result[3], 16);
14
+ }
15
+ r /= 255, g /= 255, b /= 255;
16
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
17
+ let h, s, l = (max + min) / 2;
18
+ if (max == min) {
19
+ h = s = 0;
20
+ } else {
21
+ const d = max - min;
22
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
23
+ switch (max) {
24
+ case r:
25
+ h = (g - b) / d + (g < b ? 6 : 0);
26
+ break;
27
+ case g:
28
+ h = (b - r) / d + 2;
29
+ break;
30
+ case b:
31
+ h = (r - g) / d + 4;
32
+ break;
253
33
  }
34
+ }
35
+ h = Math.round(h ? h * 360 : 0);
36
+ s = Math.round(s * 100);
37
+ l = Math.round(l * 100);
38
+ cssString = h + "," + s + "%," + l + "%";
39
+ cssString = !valuesOnly ? "hsl(" + cssString + ")" : cssString;
40
+ return cssString;
41
+ };
42
+ const hexToHSL = (H) => {
43
+ let r = 0, g = 0, b = 0;
44
+ if (H.length == 4) {
45
+ r = parseInt("0x" + H[1] + H[1]);
46
+ g = parseInt("0x" + H[2] + H[2]);
47
+ b = parseInt("0x" + H[3] + H[3]);
48
+ } else if (H.length == 7) {
49
+ r = parseInt("0x" + H[1] + H[2]);
50
+ g = parseInt("0x" + H[3] + H[4]);
51
+ b = parseInt("0x" + H[5] + H[6]);
52
+ }
53
+ r /= 255;
54
+ g /= 255;
55
+ b /= 255;
56
+ let h = 0, s = 0, l = 0;
57
+ const cmin = Math.min(r, g, b), cmax = Math.max(r, g, b), delta = cmax - cmin;
58
+ if (delta == 0) h = 0;
59
+ else if (cmax == r) h = (g - b) / delta % 6;
60
+ else if (cmax == g) h = (b - r) / delta + 2;
61
+ else h = (r - g) / delta + 4;
62
+ h = Math.round(h * 60);
63
+ if (h < 0) h += 360;
64
+ l = (cmax + cmin) / 2;
65
+ s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
66
+ s = +(s * 100).toFixed(1);
67
+ l = +(l * 100).toFixed(1);
68
+ return [h, s, l];
69
+ };
70
+ const hexToHsluv = (hex) => {
71
+ const conv = new Hsluv();
72
+ conv.hex = hex;
73
+ conv.hexToHsluv();
74
+ return [conv.hsluv_h, conv.hsluv_s, conv.hsluv_l];
75
+ };
76
+ const hslArrToCss = (HSL) => {
77
+ return "hsl(" + HSL[0] + "," + HSL[1] + "%," + HSL[2] + "%)";
78
+ };
79
+ const HSLToHex = (h, s, l) => {
80
+ s /= 100;
81
+ l /= 100;
82
+ let r = 0, g = 0, b = 0;
83
+ const c = (1 - Math.abs(2 * l - 1)) * s, x = c * (1 - Math.abs(h / 60 % 2 - 1)), m = l - c / 2;
84
+ if (0 <= h && h < 60) {
85
+ r = c;
86
+ g = x;
87
+ b = 0;
88
+ } else if (60 <= h && h < 120) {
89
+ r = x;
90
+ g = c;
91
+ b = 0;
92
+ } else if (120 <= h && h < 180) {
93
+ r = 0;
94
+ g = c;
95
+ b = x;
96
+ } else if (180 <= h && h < 240) {
97
+ r = 0;
98
+ g = x;
99
+ b = c;
100
+ } else if (240 <= h && h < 300) {
101
+ r = x;
102
+ g = 0;
103
+ b = c;
104
+ } else if (300 <= h && h < 360) {
105
+ r = c;
106
+ g = 0;
107
+ b = x;
108
+ }
109
+ r = parseInt(Math.round((r + m) * 255).toString(16), 16);
110
+ g = parseInt(Math.round((g + m) * 255).toString(16), 16);
111
+ b = parseInt(Math.round((b + m) * 255).toString(16), 16);
112
+ if (r.toString().length == 1) r = parseInt("0" + r.toString(), 10);
113
+ if (g.toString().length == 1) g = parseInt("0" + g.toString(), 10);
114
+ if (b.toString().length == 1) b = parseInt("0" + b.toString(), 10);
115
+ return "#" + r + g + b;
116
+ };
117
+ const hexToRgb = (hex) => {
118
+ const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
119
+ hex = hex.replace(shorthandRegex, function(m, r, g, b) {
120
+ return r + r + g + g + b + b;
121
+ });
122
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
123
+ return result ? {
124
+ r: parseInt(result[1], 16),
125
+ g: parseInt(result[2], 16),
126
+ b: parseInt(result[3], 16)
127
+ } : null;
128
+ };
129
+ const luminanceFromRgb = (r, g, b) => {
130
+ const a = [Number(r), Number(g), Number(b)].map(function(v) {
131
+ v /= 255;
132
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
133
+ });
134
+ return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
135
+ };
136
+ const luminanceFromHex = (hex) => {
137
+ const rgb = hexToRgb(hex);
138
+ if (rgb) {
139
+ const r = rgb.r.toString();
140
+ const g = rgb.g.toString();
141
+ const b = rgb.b.toString();
142
+ return luminanceFromRgb(r, g, b);
143
+ }
144
+ return 2;
145
+ };
146
+ const getRatioFromLum = (lum1, lum2) => {
147
+ if (lum1 !== null && lum2 !== null) {
148
+ return (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05);
149
+ } else {
254
150
  return -1;
255
- };
256
- /**
257
- * Get the contrast ratio between two colors at a specific lightness
258
- *
259
- * @param lightness The lightness value
260
- * @param mainColor The main color
261
- * @param backgroundColor The background color
262
- * @returns The contrast ratio
263
- */ export const getContrastFromLightness = (lightness, mainColor, backgroundColor)=>{
264
- const conv = new Hsluv();
265
- conv.hex = mainColor;
266
- conv.hexToHsluv();
267
- conv.hsluv_l = lightness;
268
- conv.hsluvToHex();
269
- const lightMainColor = conv.hex;
270
- const lum1 = luminanceFromHex(lightMainColor);
271
- const lum2 = luminanceFromHex(backgroundColor);
272
- const ratio = getRatioFromLum(lum1 ?? 0, lum2 ?? 0);
273
- return ratio;
274
- };
275
- /**
276
- * Maps the numbers from [start1 - end1] to the range [start2 - end2], maintaining the proportionality between the numbers in the ranges using lineaer interpolation.
277
- */ // const mapRange = (value: number, start1: number, end1: number, start2: number, end2: number) => {
278
- // return start2 + ((value - start1) * (end2 - start2)) / (end1 - start1);
279
- // };
280
- /**
281
- * Check if two colors have enough contrast to be used together
282
- *
283
- * @param {CssColor} color1 The first color
284
- * @param {CssColor} color2 The second color
285
- * @returns {boolean} If the colors have enough contrast
286
- */ export const areColorsContrasting = (color1, color2, type = 'aa')=>{
287
- const contrast = getContrastFromHex(color1, color2);
288
- if (contrast !== null) {
289
- if (type === 'aaa') {
290
- return contrast >= 7;
291
- } else if (type === 'aa') {
292
- return contrast >= 4.5;
293
- } else {
294
- return contrast >= 3;
295
- }
296
- }
297
- return false;
298
- };
299
- export const getApcaContrastLc = (textColor, backgroundColor)=>{
300
- const textColorRgb = hexToRgb(textColor);
301
- const backgroundColorRgb = hexToRgb(backgroundColor);
302
- if (textColorRgb && backgroundColorRgb) {
303
- return APCAcontrast(sRGBtoY([
304
- textColorRgb.r,
305
- textColorRgb.g,
306
- textColorRgb.b
307
- ]), sRGBtoY([
308
- backgroundColorRgb.r,
309
- backgroundColorRgb.g,
310
- backgroundColorRgb.b
311
- ]));
151
+ }
152
+ };
153
+ const getHslLightessFromHex = (hex) => {
154
+ return chroma(hex).hsl()[2];
155
+ };
156
+ const getHslSaturationFromHex = (hex) => {
157
+ return chroma(hex).hsl()[1];
158
+ };
159
+ const getLightnessFromHex = (hex) => {
160
+ const conv = new Hsluv();
161
+ conv.hex = hex;
162
+ conv.hexToHsluv();
163
+ return Number(conv.hsluv_l.toFixed(0));
164
+ };
165
+ const getContrastFromHex = (color1, color2) => {
166
+ const lum1 = luminanceFromHex(color1);
167
+ const lum2 = luminanceFromHex(color2);
168
+ if (lum1 !== null && lum2 !== null) {
169
+ return getRatioFromLum(lum1, lum2);
170
+ }
171
+ return -1;
172
+ };
173
+ const getContrastFromLightness = (lightness, mainColor, backgroundColor) => {
174
+ const conv = new Hsluv();
175
+ conv.hex = mainColor;
176
+ conv.hexToHsluv();
177
+ conv.hsluv_l = lightness;
178
+ conv.hsluvToHex();
179
+ const lightMainColor = conv.hex;
180
+ const lum1 = luminanceFromHex(lightMainColor);
181
+ const lum2 = luminanceFromHex(backgroundColor);
182
+ const ratio = getRatioFromLum(lum1 ?? 0, lum2 ?? 0);
183
+ return ratio;
184
+ };
185
+ const areColorsContrasting = (color1, color2, type = "aa") => {
186
+ const contrast = getContrastFromHex(color1, color2);
187
+ if (contrast !== null) {
188
+ if (type === "aaa") {
189
+ return contrast >= 7;
190
+ } else if (type === "aa") {
191
+ return contrast >= 4.5;
192
+ } else {
193
+ return contrast >= 3;
312
194
  }
313
- return 0;
314
- };
315
- /**
316
- * Check if aa string value is a HEX color
317
- *
318
- * @param {string} hex The string to check
319
- * @returns {boolean} If the string is a HEX color
320
- */ export const isHexColor = (hex)=>{
321
- return typeof hex === 'string' && hex.length === 6 && !isNaN(Number('0x' + hex));
195
+ }
196
+ return false;
197
+ };
198
+ const getApcaContrastLc = (textColor, backgroundColor) => {
199
+ const textColorRgb = hexToRgb(textColor);
200
+ const backgroundColorRgb = hexToRgb(backgroundColor);
201
+ if (textColorRgb && backgroundColorRgb) {
202
+ return APCAcontrast(
203
+ sRGBtoY([textColorRgb.r, textColorRgb.g, textColorRgb.b]),
204
+ sRGBtoY([backgroundColorRgb.r, backgroundColorRgb.g, backgroundColorRgb.b])
205
+ );
206
+ }
207
+ return 0;
208
+ };
209
+ const isHexColor = (hex) => {
210
+ return typeof hex === "string" && hex.length === 6 && !isNaN(Number("0x" + hex));
211
+ };
212
+ export {
213
+ HSLToHex,
214
+ areColorsContrasting,
215
+ getApcaContrastLc,
216
+ getContrastFromHex,
217
+ getContrastFromLightness,
218
+ getHslLightessFromHex,
219
+ getHslSaturationFromHex,
220
+ getLightnessFromHex,
221
+ getRatioFromLum,
222
+ hexToCssHsl,
223
+ hexToHSL,
224
+ hexToHsluv,
225
+ hexToRgb,
226
+ hslArrToCss,
227
+ isHexColor,
228
+ luminanceFromHex,
229
+ luminanceFromRgb
322
230
  };
@@ -1,3 +1,3 @@
1
- export * from "./colorUtils.js";
2
- export * from "./themeUtils.js";
3
- export * from "./types.js";
1
+ export * from "./colorUtils";
2
+ export * from "./themeUtils";
3
+ export * from "./types";