@skbkontur/colors 2.0.1 → 2.0.2

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 (44) hide show
  1. package/lib/get-colors.js +19 -1
  2. package/lib/get-colors.ts +9 -1
  3. package/package.json +2 -2
  4. package/tokens-mobile/brand-blue-deep_accent-brand.json +117 -117
  5. package/tokens-mobile/brand-blue-deep_accent-gray.json +135 -135
  6. package/tokens-mobile/brand-blue_accent-brand.json +117 -117
  7. package/tokens-mobile/brand-blue_accent-gray.json +135 -135
  8. package/tokens-mobile/brand-green_accent-brand.json +117 -117
  9. package/tokens-mobile/brand-green_accent-gray.json +135 -135
  10. package/tokens-mobile/brand-mint_accent-brand.json +117 -117
  11. package/tokens-mobile/brand-mint_accent-gray.json +135 -135
  12. package/tokens-mobile/brand-orange_accent-gray.json +135 -135
  13. package/tokens-mobile/brand-purple_accent-brand.json +117 -117
  14. package/tokens-mobile/brand-purple_accent-gray.json +135 -135
  15. package/tokens-mobile/brand-red_accent-gray.json +135 -135
  16. package/tokens-mobile/brand-violet_accent-brand.json +117 -117
  17. package/tokens-mobile/brand-violet_accent-gray.json +135 -135
  18. package/.gitignore +0 -10
  19. package/.npmignore +0 -10
  20. package/CHANGELOG.md +0 -117
  21. package/__docs__/Colors.docs.stories.tsx +0 -1578
  22. package/__docs__/Colors.mdx +0 -228
  23. package/__docs__/ColorsAPI.docs.stories.tsx +0 -954
  24. package/__docs__/ColorsAPI.mdx +0 -133
  25. package/__stories__/colors.stories.tsx +0 -452
  26. package/__tests__/convert-color.test.ts +0 -23
  27. package/__tests__/create-tokens-from-figma.test.ts +0 -162
  28. package/__tests__/format-variable.test.ts +0 -16
  29. package/__tests__/get-colors-base.test.ts +0 -55
  30. package/__tests__/get-colors.test.ts +0 -75
  31. package/__tests__/get-interactions.test.ts +0 -37
  32. package/__tests__/get-logo.test.ts +0 -24
  33. package/__tests__/get-palette.test.ts +0 -43
  34. package/__tests__/get-promo.test.ts +0 -32
  35. package/colors-default-dark.ts +0 -332
  36. package/colors-default-light.ts +0 -336
  37. package/colors.less +0 -319
  38. package/colors.scss +0 -319
  39. package/colors.ts +0 -319
  40. package/scripts/create-tokens-files.ts +0 -424
  41. package/scripts/create-tokens-from-figma.ts +0 -376
  42. package/scripts/figma-tokens-base.json +0 -3499
  43. package/scripts/figma-tokens.json +0 -710
  44. package/tsconfig.json +0 -8
@@ -1,424 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
-
4
- import { camelCaseToKebabCase, kebabCaseToCamelCase } from '../lib/utils/format-variable.js';
5
- import { getColors } from '../lib/get-colors.js';
6
- import * as DEFAULT_SWATCH from '../lib/consts/default-swatch.js';
7
- import type { ColorObject, ColorValue } from '../lib/types/tokens.js';
8
- import type { ConfigOptions } from '../lib/get-colors-base.js';
9
-
10
- type ColorFormat = ConfigOptions['format'];
11
-
12
- const DEFAULT_BRAND = 'red';
13
- const DEFAULT_ACCENT = 'gray';
14
-
15
- interface SaveTokensOptions {
16
- colorBrand: string;
17
- colorAccent: string;
18
- colorFormat?: ColorFormat;
19
- tokens: any;
20
- tokensIsFlat?: boolean;
21
- tokensCSSPrefix?: string;
22
- tokensJSVariableName?: string;
23
- fileSingleOutputName?: string;
24
- fileOutputDir: string;
25
- fileFormat: 'json' | 'css' | 'less' | 'scss' | 'js' | 'js-css-vars' | 'js-css-vars-fallback';
26
- removePressedAndHover?: boolean;
27
- }
28
-
29
- const TOKENS_OUTPUT = path.join(import.meta.dirname, '..');
30
-
31
- for (const accentVariant of ['brand', 'gray']) {
32
- for (const brandColorKey in DEFAULT_SWATCH.brand) {
33
- if (accentVariant === 'brand' && (brandColorKey === 'red' || brandColorKey === 'orange')) {
34
- continue;
35
- }
36
-
37
- const tokens = {
38
- light: getColors({
39
- brand: brandColorKey,
40
- accent: accentVariant,
41
- theme: 'light',
42
- }),
43
- dark: getColors({
44
- brand: brandColorKey,
45
- accent: accentVariant,
46
- theme: 'dark',
47
- }),
48
- };
49
-
50
- const tokensMobile = {
51
- light: getColors({
52
- brand: brandColorKey,
53
- accent: accentVariant,
54
- theme: 'light',
55
- format: 'hex-aarrggbb',
56
- }),
57
- dark: getColors({
58
- brand: brandColorKey,
59
- accent: accentVariant,
60
- theme: 'dark',
61
- format: 'hex-aarrggbb',
62
- }),
63
- };
64
-
65
- const brandFileName = camelCaseToKebabCase(brandColorKey);
66
-
67
- saveTokens({
68
- tokens,
69
- colorBrand: brandFileName,
70
- colorAccent: accentVariant,
71
- fileOutputDir: path.join(TOKENS_OUTPUT, 'tokens'),
72
- fileFormat: 'css',
73
- tokensCSSPrefix: 'k-color',
74
- });
75
-
76
- saveTokens({
77
- tokens: tokensMobile,
78
- colorBrand: brandFileName,
79
- colorAccent: accentVariant,
80
- fileOutputDir: path.join(TOKENS_OUTPUT, 'tokens-mobile'),
81
- fileFormat: 'json',
82
- tokensIsFlat: true,
83
- removePressedAndHover: true,
84
- });
85
- }
86
- }
87
-
88
- const tokensDefault = {
89
- light: getColors({
90
- brand: DEFAULT_BRAND,
91
- accent: DEFAULT_ACCENT,
92
- theme: 'light',
93
- }),
94
- dark: getColors({
95
- brand: DEFAULT_BRAND,
96
- accent: DEFAULT_ACCENT,
97
- theme: 'dark',
98
- }),
99
- };
100
-
101
- const defaultBrandFileName = camelCaseToKebabCase(DEFAULT_BRAND);
102
-
103
- saveTokens({
104
- tokens: tokensDefault,
105
- colorBrand: defaultBrandFileName,
106
- colorAccent: DEFAULT_ACCENT,
107
- fileOutputDir: '',
108
- fileFormat: 'scss',
109
- tokensIsFlat: true,
110
- tokensCSSPrefix: 'k-color',
111
- fileSingleOutputName: path.join(TOKENS_OUTPUT, 'colors.scss'),
112
- });
113
-
114
- saveTokens({
115
- tokens: tokensDefault,
116
- colorBrand: defaultBrandFileName,
117
- colorAccent: DEFAULT_ACCENT,
118
- fileOutputDir: '',
119
- fileFormat: 'less',
120
- tokensIsFlat: true,
121
- tokensCSSPrefix: 'k-color',
122
- fileSingleOutputName: path.join(TOKENS_OUTPUT, 'colors.less'),
123
- });
124
-
125
- saveTokens({
126
- tokens: tokensDefault,
127
- colorBrand: defaultBrandFileName,
128
- colorAccent: DEFAULT_ACCENT,
129
- fileOutputDir: '',
130
- fileFormat: 'js-css-vars',
131
- tokensIsFlat: true,
132
- tokensCSSPrefix: 'k-color',
133
- fileSingleOutputName: path.join(TOKENS_OUTPUT, 'colors.ts'),
134
- });
135
-
136
- saveTokens({
137
- tokens: { light: tokensDefault.light },
138
- colorBrand: defaultBrandFileName,
139
- colorAccent: DEFAULT_ACCENT,
140
- fileOutputDir: '',
141
- fileFormat: 'js-css-vars-fallback',
142
- tokensIsFlat: true,
143
- tokensCSSPrefix: 'k-color',
144
- fileSingleOutputName: path.join(TOKENS_OUTPUT, 'colors-default-light.ts'),
145
- });
146
-
147
- saveTokens({
148
- tokens: { dark: tokensDefault.dark },
149
- colorBrand: defaultBrandFileName,
150
- colorAccent: DEFAULT_ACCENT,
151
- fileOutputDir: '',
152
- fileFormat: 'js-css-vars-fallback',
153
- tokensIsFlat: true,
154
- tokensCSSPrefix: 'k-color',
155
- fileSingleOutputName: path.join(TOKENS_OUTPUT, 'colors-default-dark.ts'),
156
- });
157
-
158
- function saveTokens({
159
- tokens,
160
- colorBrand,
161
- colorAccent,
162
- tokensIsFlat,
163
- tokensCSSPrefix,
164
- tokensJSVariableName,
165
- fileSingleOutputName,
166
- fileOutputDir,
167
- fileFormat,
168
- removePressedAndHover,
169
- }: SaveTokensOptions) {
170
- const isFlat = tokensIsFlat ?? false;
171
- const cssPrefix = tokensCSSPrefix ?? '';
172
-
173
- const brandFileName = colorBrand;
174
- const accentVariant = colorAccent;
175
- const outputDir = fileOutputDir;
176
- const format = fileFormat;
177
- const singleOutputFile = fileSingleOutputName;
178
- const jsVariableName = tokensJSVariableName;
179
-
180
- if (!singleOutputFile) {
181
- fs.mkdirSync(outputDir, { recursive: true });
182
- }
183
-
184
- const baseFileName = `brand-${brandFileName}_accent-${accentVariant.toLowerCase()}`;
185
- let fileName = baseFileName;
186
-
187
- if (!isFlat && (format === 'json' || format === 'js')) {
188
- fileName += '.tree';
189
- }
190
-
191
- const finalOutputFile = singleOutputFile || path.join(outputDir, `${fileName}.${format}`);
192
-
193
- switch (format) {
194
- case 'json': {
195
- const tokensToWrite = isFlat ? JSON.parse(JSON.stringify(tokens)) : tokens;
196
-
197
- if (removePressedAndHover) {
198
- if (tokensToWrite.light) {
199
- removeStateTokens(tokensToWrite.light);
200
- }
201
- if (tokensToWrite.dark) {
202
- removeStateTokens(tokensToWrite.dark);
203
- }
204
- }
205
-
206
- const toCamelCaseFlat = (tokens: any) =>
207
- Object.entries(flattenHybridCase(tokens)).reduce((acc: any, [key, value]) => {
208
- acc[kebabCaseToCamelCase(key)] = value;
209
- return acc;
210
- }, {});
211
-
212
- const flatLight = toCamelCaseFlat(tokensToWrite.light);
213
- const flatDark = toCamelCaseFlat(tokensToWrite.dark);
214
-
215
- const themedTokens: any = {};
216
- const allKeys = new Set([...Object.keys(flatLight), ...Object.keys(flatDark)]);
217
-
218
- // @ts-ignore
219
- for (const key of allKeys) {
220
- themedTokens[key] = {
221
- light: flatLight[key],
222
- dark: flatDark[key],
223
- };
224
- }
225
-
226
- fs.writeFileSync(finalOutputFile, JSON.stringify(themedTokens, null, 2));
227
- break;
228
- }
229
-
230
- case 'css': {
231
- const brandDataSelector = `[data-k-brand="${brandFileName}"][data-k-accent="${accentVariant.toLowerCase()}"]`;
232
- const baseSelector = brandDataSelector;
233
-
234
- let cssContent = '';
235
-
236
- const hasThemes = tokens.light || tokens.dark;
237
-
238
- if (hasThemes) {
239
- const lightTokens = tokens.light;
240
- const flattenedLightTokens = flattenHybridCase(lightTokens);
241
- const lightVars = Object.entries(flattenedLightTokens)
242
- .map(([key, value]) => ` --${cssPrefix}-${camelCaseToKebabCase(key)}: ${value};`)
243
- .join('\n');
244
-
245
- cssContent += `${baseSelector} {\n${lightVars}\n}\n\n`;
246
-
247
- if (tokens.dark) {
248
- const darkTokens = tokens.dark;
249
- const flattenedDarkTokens = flattenHybridCase(darkTokens);
250
- const darkVars = Object.entries(flattenedDarkTokens)
251
- .map(([key, value]) => ` --${cssPrefix}-${camelCaseToKebabCase(key)}: ${value};`)
252
- .join('\n');
253
-
254
- const darkSelector = `${baseSelector}[data-k-theme="dark"]`;
255
- cssContent += `${darkSelector} {\n${darkVars}\n}\n\n`;
256
- }
257
- }
258
-
259
- fs.writeFileSync(finalOutputFile, cssContent.trim());
260
- break;
261
- }
262
-
263
- case 'less':
264
- case 'scss': {
265
- const varPrefix = format === 'less' ? '@color' : '$color';
266
-
267
- const lessScssVars: string[] = [];
268
- const hasThemes = tokens.light || tokens.dark;
269
- const themeTokens = hasThemes ? tokens.light : tokens;
270
-
271
- if (themeTokens) {
272
- const flattenedTokens = flattenHybridCase(themeTokens);
273
-
274
- const themeVars = Object.entries(flattenedTokens).map(([key]) => {
275
- const cssVarName = camelCaseToKebabCase(key);
276
-
277
- return `${varPrefix}${cssVarName}: var(--${cssPrefix}-${cssVarName});`;
278
- });
279
-
280
- lessScssVars.push(...themeVars);
281
- }
282
-
283
- const content = lessScssVars.join('\n');
284
-
285
- fs.writeFileSync(finalOutputFile, content.trim() + '\n');
286
- break;
287
- }
288
-
289
- case 'js-css-vars': {
290
- const jsCssVars: string[] = [];
291
- const hasThemes = tokens.light || tokens.dark;
292
- const themeTokens = hasThemes ? tokens.light : tokens;
293
-
294
- if (themeTokens) {
295
- const flattenedTokens = flattenHybridCase(themeTokens);
296
-
297
- const jsVars = Object.entries(flattenedTokens).map(([key]) => {
298
- const cssVarName = camelCaseToKebabCase(key);
299
- const jsVarNameCamel = kebabCaseToCamelCase(cssVarName);
300
- const cssVarReference = `var(--${cssPrefix}-${cssVarName})`;
301
-
302
- return `export const ${jsVarNameCamel} = "${cssVarReference}";`;
303
- });
304
-
305
- jsCssVars.push(...jsVars);
306
- }
307
-
308
- const content = jsCssVars.join('\n');
309
-
310
- fs.writeFileSync(finalOutputFile, content.trim() + '\n');
311
- break;
312
- }
313
-
314
- case 'js-css-vars-fallback': {
315
- const jsCssVars: string[] = [];
316
-
317
- const themeKey = tokens.light ? 'light' : 'dark';
318
- const themeTokens = tokens[themeKey];
319
-
320
- if (themeTokens) {
321
- const flattenedTokens = flattenHybridCase(themeTokens);
322
-
323
- const jsVars = Object.entries(flattenedTokens).map(([key, value]) => {
324
- const cssVarName = camelCaseToKebabCase(key);
325
- const jsVarNameCamel = kebabCaseToCamelCase(cssVarName);
326
-
327
- const cssVarReference = `var(--${cssPrefix}-${cssVarName}, ${value})`;
328
-
329
- return `export const ${jsVarNameCamel} = "${cssVarReference}";`;
330
- });
331
-
332
- jsCssVars.push(...jsVars);
333
- }
334
-
335
- const content = jsCssVars.join('\n');
336
- fs.writeFileSync(finalOutputFile, content.trim() + '\n');
337
- break;
338
- }
339
- case 'js': {
340
- let jsTokens;
341
-
342
- const toCamelCaseFlat = (tokens: any) =>
343
- Object.entries(flattenObject(tokens)).reduce((acc: any, [key, value]) => {
344
- acc[kebabCaseToCamelCase(key)] = value;
345
- return acc;
346
- }, {});
347
-
348
- if (isFlat) {
349
- jsTokens = {
350
- light: toCamelCaseFlat(tokens.light),
351
- dark: toCamelCaseFlat(tokens.dark),
352
- };
353
-
354
- const jsContent: string = `export const ${jsVariableName} = ${JSON.stringify(jsTokens, null, 2)};`;
355
- fs.writeFileSync(finalOutputFile, jsContent);
356
- } else {
357
- jsTokens = tokens;
358
- let jsContent = `export const ${jsVariableName} = ${JSON.stringify(jsTokens, null, 2)};`;
359
- jsContent = unquoteJsKeys(jsContent);
360
- fs.writeFileSync(finalOutputFile, jsContent);
361
- }
362
- break;
363
- }
364
-
365
- default: {
366
- console.error(`Unsupported format: ${format}`);
367
- break;
368
- }
369
- }
370
- }
371
-
372
- function unquoteJsKeys(objString: string): string {
373
- return objString.replace(/"([^"]+)":/g, '$1:');
374
- }
375
-
376
- function removeStateTokens(obj: any): any {
377
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
378
- return obj;
379
- }
380
-
381
- for (const key in obj) {
382
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
383
- const camelKey = kebabCaseToCamelCase(key);
384
- if (camelKey.includes('Pressed') || camelKey.includes('Hover')) {
385
- delete obj[key];
386
- } else if (typeof obj[key] === 'object' && obj[key] !== null) {
387
- removeStateTokens(obj[key]);
388
- }
389
- }
390
- }
391
- return obj;
392
- }
393
-
394
- function flattenHybridCase(obj: any, prefix = ''): any {
395
- return Object.keys(obj).reduce((acc, key) => {
396
- const newKey = prefix + (prefix ? '-' : '') + key;
397
- if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
398
- Object.assign(acc, flattenHybridCase(obj[key], newKey));
399
- } else {
400
- // @ts-ignore
401
- acc[newKey] = obj[key];
402
- }
403
- return acc;
404
- }, {});
405
- }
406
-
407
- function flattenObject(obj: ColorObject, prefix = ''): { [key: string]: string | ColorValue } {
408
- let result: { [key: string]: string | ColorValue } = {};
409
- for (const key in obj) {
410
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
411
- const newKey = prefix ? `${prefix}-${camelCaseToKebabCase(key)}` : key;
412
- if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
413
- result = {
414
- ...result,
415
- // @ts-ignore
416
- ...flattenObject(obj[key], newKey),
417
- };
418
- } else {
419
- result[newKey] = obj[key];
420
- }
421
- }
422
- }
423
- return result;
424
- }