@sb1/ffe-core 33.2.0 → 100.0.3
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.
- package/README.md +8 -8
- package/css/colors-semantic-tailwind-4.css +6 -0
- package/css/colors-semantic.css +136 -100
- package/css/ffe.css +138 -101
- package/less/colors-semantic-chevron.less +1 -1
- package/less/colors-semantic.less +136 -100
- package/less/dimensions.less +1 -0
- package/less/variables.less +0 -1
- package/lib/semanticColors.js +7 -1
- package/lib/semanticColorsTailwind.js +7 -1
- package/package.json +6 -4
- package/scripts/build-colors/build-colors.cjs +115 -0
- package/scripts/build-colors/json/json.cjs +12 -0
- package/scripts/build-colors/mobile/android.cjs +99 -0
- package/scripts/build-colors/mobile/android.test.js +98 -0
- package/scripts/build-colors/mobile/ios.cjs +205 -0
- package/scripts/build-colors/web/chevron.cjs +44 -0
- package/scripts/build-colors/web/color-names.cjs +24 -0
- package/scripts/build-colors/web/css.cjs +78 -0
- package/scripts/build-colors/web/js.cjs +44 -0
- package/scripts/build-colors/web/tailwind.cjs +36 -0
- package/scripts/build-colors/web/tailwind4.cjs +24 -0
- package/scripts/build-colors/web/web.cjs +18 -0
- package/scripts/build-custom-mq.cjs +45 -0
- package/scripts/build.cjs +38 -0
- package/scripts/figma-api/color.spec.tsx +126 -0
- package/scripts/figma-api/color.ts +52 -0
- package/scripts/figma-api/figma_api.ts +41 -0
- package/scripts/figma-api/sync_figma_to_tokens.ts +57 -0
- package/scripts/figma-api/token_export.spec.tsx +359 -0
- package/scripts/figma-api/token_export.ts +99 -0
- package/scripts/figma-api/token_import.spec.tsx +1097 -0
- package/scripts/figma-api/token_import.ts +430 -0
- package/scripts/figma-api/token_types.ts +55 -0
- package/scripts/figma-api/utils.ts +11 -0
- package/scripts/lib/extractCustomProps.cjs +24 -0
- package/scripts/lib/genTypeScript.cjs +7 -0
- package/scripts/lib/renderLessVarsToCSSProps.cjs +23 -0
- package/scripts/lib/writeToFile.cjs +9 -0
- package/scripts/utils.cjs +27 -0
- package/tokens/01 Primitive.value.json +4726 -0
- package/tokens/02 Semantic.Dark.json +3942 -0
- package/tokens/02 Semantic.Light.json +3942 -0
- package/tokens/03 Context.Accent.json +2273 -0
- package/tokens/03 Context.Default.json +2273 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
|
|
4
|
-
exports['background-default'] = exports['background-subtle'] = exports['surface-primary-default'] = exports['surface-primary-default-hover'] = exports['surface-primary-default-pressed'] = exports['surface-secondary-default'] = exports['surface-secondary-default-hover'] = exports['surface-secondary-default-pressed'] = exports['surface-tertiary-default'] = exports['surface-tertiary-default-hover'] = exports['surface-tertiary-default-pressed'] = exports['surface-neutral-default'] = exports['surface-neutral-default-hover'] = exports['surface-neutral-default-pressed'] = exports['surface-feedback-info'] = exports['surface-feedback-success'] = exports['surface-feedback-warning'] = exports['surface-feedback-critical'] = exports['surface-feedback-tip'] = exports['fill-primary-default'] = exports['fill-primary-default-hover'] = exports['fill-primary-default-pressed'] = exports['fill-primary-selected-default'] = exports['fill-primary-selected-hover'] = exports['fill-primary-selected-pressed'] = exports['fill-primary-subtle'] = exports['fill-primary-subtle-hover'] = exports['fill-primary-subtle-pressed'] = exports['fill-primary-invisible'] = exports['fill-secondary-default'] = exports['fill-secondary-default-hover'] = exports['fill-secondary-default-pressed'] = exports['fill-secondary-subtle'] = exports['fill-secondary-subtle-hover'] = exports['fill-secondary-subtle-pressed'] = exports['fill-tertiary-default'] = exports['fill-tertiary-default-hover'] = exports['fill-tertiary-default-pressed'] = exports['fill-tertiary-subtle'] = exports['fill-tertiary-subtle-hover'] = exports['fill-tertiary-subtle-pressed'] = exports['fill-neutral-default'] = exports['fill-neutral-default-hover'] = exports['fill-neutral-default-pressed'] = exports['fill-neutral-subtle'] = exports['fill-neutral-subtle-hover'] = exports['fill-neutral-subtle-pressed'] = exports['fill-neutral-extra-subtle'] = exports['fill-neutral-extra-subtle-hover'] = exports['fill-neutral-extra-subtle-pressed'] = exports['fill-feedback-info'] = exports['fill-feedback-info-subtle'] = exports['fill-feedback-success'] = exports['fill-feedback-success-subtle'] = exports['fill-feedback-warning'] = exports['fill-feedback-warning-subtle'] = exports['fill-feedback-critical'] = exports['fill-feedback-critical-subtle'] = exports['fill-feedback-tip'] = exports['fill-feedback-tip-subtle'] = exports['foreground-default'] = exports['foreground-subtle'] = exports['foreground-emphasis'] = exports['foreground-inverse'] = exports['foreground-interactive-link'] = exports['foreground-interactive-link-hover'] = exports['foreground-interactive-link-pressed'] = exports['foreground-interactive-link-active'] = exports['foreground-feedback-info'] = exports['foreground-feedback-success'] = exports['foreground-feedback-warning'] = exports['foreground-feedback-critical'] = exports['foreground-feedback-tip'] = exports['component-form-input-foreground-default'] = exports['component-form-input-foreground-subtle'] = exports['component-form-input-foreground-placeholder'] = exports['component-form-input-foreground-disabled'] = exports['component-form-input-foreground-read-only'] = exports['component-form-input-foreground-error'] = exports['component-form-input-border-active'] = exports['component-form-input-fill-default'] = exports['component-form-input-fill-default-hover'] = exports['component-form-input-fill-default-pressed'] = exports['component-form-input-fill-disabled'] = exports['component-form-input-fill-read-only'] = exports['component-form-input-fill-error'] = exports['component-form-toggleswitch-handle-default'] = exports['component-form-toggleswitch-fill-default'] = exports['component-form-toggleswitch-fill-default-hover'] = exports['component-form-toggleswitch-fill-default-pressed'] = exports['component-form-toggleswitch-fill-selected'] = exports['component-form-toggleswitch-fill-selected-hover'] = exports['component-form-toggleswitch-fill-selected-pressed'] = exports['component-form-toggleswitch-fill-critical'] = exports['component-button-action-border-default'] = exports['component-button-action-border-hover'] = exports['component-button-action-border-pressed'] = exports['component-button-action-fill-default'] = exports['component-button-action-fill-hover'] = exports['component-button-action-fill-pressed'] = exports['component-button-action-foreground-default'] = exports['component-button-action-foreground-hover'] = exports['component-button-primary-border-default'] = exports['component-button-primary-border-hover'] = exports['component-button-primary-border-pressed'] = exports['component-button-primary-fill-default'] = exports['component-button-primary-fill-hover'] = exports['component-button-primary-fill-pressed'] = exports['component-button-primary-foreground-default'] = exports['component-button-primary-foreground-hover'] = exports['component-button-secondary-border-default'] = exports['component-button-secondary-border-hover'] = exports['component-button-secondary-border-pressed'] = exports['component-button-secondary-fill-default'] = exports['component-button-secondary-fill-hover'] = exports['component-button-secondary-fill-pressed'] = exports['component-button-secondary-foreground-default'] = exports['component-button-secondary-foreground-hover'] = exports['component-button-tertiary-fill-default'] = exports['component-button-tertiary-fill-hover'] = exports['component-button-tertiary-fill-pressed'] = exports['component-button-tertiary-foreground-default'] = exports['component-button-tertiary-foreground-hover'] = exports['component-logo-name'] = exports['component-logo-number1'] = exports['component-logo-circle-dark-red'] = exports['component-logo-circle-light-red'] = exports['border-primary-default'] = exports['border-primary-default-hover'] = exports['border-primary-default-pressed'] = exports['border-primary-subtle'] = exports['border-primary-subtle-hover'] = exports['border-primary-subtle-pressed'] = exports['border-primary-emphasis'] = exports['border-feedback-info'] = exports['border-feedback-success'] = exports['border-feedback-warning'] = exports['border-feedback-critical'] = exports['border-feedback-tip'] = exports['border-interactive-focus'] = exports['border-interactive-selected'] = void 0
|
|
4
|
+
exports['background-default'] = exports['background-subtle'] = exports['surface-primary-default'] = exports['surface-primary-default-hover'] = exports['surface-primary-default-pressed'] = exports['surface-secondary-default'] = exports['surface-secondary-default-hover'] = exports['surface-secondary-default-pressed'] = exports['surface-tertiary-default'] = exports['surface-tertiary-default-hover'] = exports['surface-tertiary-default-pressed'] = exports['surface-neutral-default'] = exports['surface-neutral-default-hover'] = exports['surface-neutral-default-pressed'] = exports['surface-feedback-info'] = exports['surface-feedback-success'] = exports['surface-feedback-warning'] = exports['surface-feedback-critical'] = exports['surface-feedback-tip'] = exports['fill-primary-default'] = exports['fill-primary-default-hover'] = exports['fill-primary-default-pressed'] = exports['fill-primary-selected-default'] = exports['fill-primary-selected-hover'] = exports['fill-primary-selected-pressed'] = exports['fill-primary-subtle'] = exports['fill-primary-subtle-hover'] = exports['fill-primary-subtle-pressed'] = exports['fill-primary-invisible'] = exports['fill-secondary-default'] = exports['fill-secondary-default-hover'] = exports['fill-secondary-default-pressed'] = exports['fill-secondary-subtle'] = exports['fill-secondary-subtle-hover'] = exports['fill-secondary-subtle-pressed'] = exports['fill-tertiary-default'] = exports['fill-tertiary-default-hover'] = exports['fill-tertiary-default-pressed'] = exports['fill-tertiary-subtle'] = exports['fill-tertiary-subtle-hover'] = exports['fill-tertiary-subtle-pressed'] = exports['fill-neutral-default'] = exports['fill-neutral-default-hover'] = exports['fill-neutral-default-pressed'] = exports['fill-neutral-subtle'] = exports['fill-neutral-subtle-hover'] = exports['fill-neutral-subtle-pressed'] = exports['fill-neutral-extra-subtle'] = exports['fill-neutral-extra-subtle-hover'] = exports['fill-neutral-extra-subtle-pressed'] = exports['fill-feedback-info'] = exports['fill-feedback-info-subtle'] = exports['fill-feedback-success'] = exports['fill-feedback-success-subtle'] = exports['fill-feedback-warning'] = exports['fill-feedback-warning-subtle'] = exports['fill-feedback-critical'] = exports['fill-feedback-critical-subtle'] = exports['fill-feedback-tip'] = exports['fill-feedback-tip-subtle'] = exports['foreground-default'] = exports['foreground-subtle'] = exports['foreground-emphasis'] = exports['foreground-inverse'] = exports['foreground-interactive-link'] = exports['foreground-interactive-link-hover'] = exports['foreground-interactive-link-pressed'] = exports['foreground-interactive-link-active'] = exports['foreground-interactive-disabled'] = exports['foreground-feedback-info'] = exports['foreground-feedback-success'] = exports['foreground-feedback-warning'] = exports['foreground-feedback-critical'] = exports['foreground-feedback-tip'] = exports['component-form-input-foreground-default'] = exports['component-form-input-foreground-subtle'] = exports['component-form-input-foreground-placeholder'] = exports['component-form-input-foreground-disabled'] = exports['component-form-input-foreground-read-only'] = exports['component-form-input-foreground-error'] = exports['component-form-input-border-active'] = exports['component-form-input-fill-default'] = exports['component-form-input-fill-default-hover'] = exports['component-form-input-fill-default-pressed'] = exports['component-form-input-fill-disabled'] = exports['component-form-input-fill-read-only'] = exports['component-form-input-fill-error'] = exports['component-form-toggleswitch-handle-default'] = exports['component-form-toggleswitch-handle-disabled'] = exports['component-form-toggleswitch-fill-default'] = exports['component-form-toggleswitch-fill-default-hover'] = exports['component-form-toggleswitch-fill-default-pressed'] = exports['component-form-toggleswitch-fill-selected'] = exports['component-form-toggleswitch-fill-selected-hover'] = exports['component-form-toggleswitch-fill-selected-pressed'] = exports['component-form-toggleswitch-fill-selected-disabled'] = exports['component-form-toggleswitch-fill-selected-read-only'] = exports['component-form-toggleswitch-fill-critical'] = exports['component-form-toggleswitch-fill-disabled'] = exports['component-form-toggleswitch-fill-read-only'] = exports['component-button-action-border-default'] = exports['component-button-action-border-hover'] = exports['component-button-action-border-pressed'] = exports['component-button-action-fill-default'] = exports['component-button-action-fill-hover'] = exports['component-button-action-fill-pressed'] = exports['component-button-action-foreground-default'] = exports['component-button-action-foreground-hover'] = exports['component-button-primary-border-default'] = exports['component-button-primary-border-hover'] = exports['component-button-primary-border-pressed'] = exports['component-button-primary-fill-default'] = exports['component-button-primary-fill-hover'] = exports['component-button-primary-fill-pressed'] = exports['component-button-primary-foreground-default'] = exports['component-button-primary-foreground-hover'] = exports['component-button-secondary-border-default'] = exports['component-button-secondary-border-hover'] = exports['component-button-secondary-border-pressed'] = exports['component-button-secondary-fill-default'] = exports['component-button-secondary-fill-hover'] = exports['component-button-secondary-fill-pressed'] = exports['component-button-secondary-foreground-default'] = exports['component-button-secondary-foreground-hover'] = exports['component-button-tertiary-fill-default'] = exports['component-button-tertiary-fill-hover'] = exports['component-button-tertiary-fill-pressed'] = exports['component-button-tertiary-foreground-default'] = exports['component-button-tertiary-foreground-hover'] = exports['component-logo-name'] = exports['component-logo-number1'] = exports['component-logo-circle-dark-red'] = exports['component-logo-circle-light-red'] = exports['border-primary-default'] = exports['border-primary-default-hover'] = exports['border-primary-default-pressed'] = exports['border-primary-subtle'] = exports['border-primary-subtle-hover'] = exports['border-primary-subtle-pressed'] = exports['border-primary-emphasis'] = exports['border-feedback-info'] = exports['border-feedback-success'] = exports['border-feedback-warning'] = exports['border-feedback-critical'] = exports['border-feedback-tip'] = exports['border-interactive-focus'] = exports['border-interactive-selected'] = void 0
|
|
5
5
|
|
|
6
6
|
exports['background-default'] = 'var(--ffe-color-background-default)';
|
|
7
7
|
exports['background-subtle'] = 'var(--ffe-color-background-subtle)';
|
|
@@ -71,6 +71,7 @@ exports['foreground-interactive-link'] = 'var(--ffe-color-foreground-interactive
|
|
|
71
71
|
exports['foreground-interactive-link-hover'] = 'var(--ffe-color-foreground-interactive-link-hover)';
|
|
72
72
|
exports['foreground-interactive-link-pressed'] = 'var(--ffe-color-foreground-interactive-link-pressed)';
|
|
73
73
|
exports['foreground-interactive-link-active'] = 'var(--ffe-color-foreground-interactive-link-active)';
|
|
74
|
+
exports['foreground-interactive-disabled'] = 'var(--ffe-color-foreground-interactive-disabled)';
|
|
74
75
|
exports['foreground-feedback-info'] = 'var(--ffe-color-foreground-feedback-info)';
|
|
75
76
|
exports['foreground-feedback-success'] = 'var(--ffe-color-foreground-feedback-success)';
|
|
76
77
|
exports['foreground-feedback-warning'] = 'var(--ffe-color-foreground-feedback-warning)';
|
|
@@ -90,13 +91,18 @@ exports['component-form-input-fill-disabled'] = 'var(--ffe-color-component-form-
|
|
|
90
91
|
exports['component-form-input-fill-read-only'] = 'var(--ffe-color-component-form-input-fill-read-only)';
|
|
91
92
|
exports['component-form-input-fill-error'] = 'var(--ffe-color-component-form-input-fill-error)';
|
|
92
93
|
exports['component-form-toggleswitch-handle-default'] = 'var(--ffe-color-component-form-toggleswitch-handle-default)';
|
|
94
|
+
exports['component-form-toggleswitch-handle-disabled'] = 'var(--ffe-color-component-form-toggleswitch-handle-disabled)';
|
|
93
95
|
exports['component-form-toggleswitch-fill-default'] = 'var(--ffe-color-component-form-toggleswitch-fill-default)';
|
|
94
96
|
exports['component-form-toggleswitch-fill-default-hover'] = 'var(--ffe-color-component-form-toggleswitch-fill-default-hover)';
|
|
95
97
|
exports['component-form-toggleswitch-fill-default-pressed'] = 'var(--ffe-color-component-form-toggleswitch-fill-default-pressed)';
|
|
96
98
|
exports['component-form-toggleswitch-fill-selected'] = 'var(--ffe-color-component-form-toggleswitch-fill-selected)';
|
|
97
99
|
exports['component-form-toggleswitch-fill-selected-hover'] = 'var(--ffe-color-component-form-toggleswitch-fill-selected-hover)';
|
|
98
100
|
exports['component-form-toggleswitch-fill-selected-pressed'] = 'var(--ffe-color-component-form-toggleswitch-fill-selected-pressed)';
|
|
101
|
+
exports['component-form-toggleswitch-fill-selected-disabled'] = 'var(--ffe-color-component-form-toggleswitch-fill-selected-disabled)';
|
|
102
|
+
exports['component-form-toggleswitch-fill-selected-read-only'] = 'var(--ffe-color-component-form-toggleswitch-fill-selected-read-only)';
|
|
99
103
|
exports['component-form-toggleswitch-fill-critical'] = 'var(--ffe-color-component-form-toggleswitch-fill-critical)';
|
|
104
|
+
exports['component-form-toggleswitch-fill-disabled'] = 'var(--ffe-color-component-form-toggleswitch-fill-disabled)';
|
|
105
|
+
exports['component-form-toggleswitch-fill-read-only'] = 'var(--ffe-color-component-form-toggleswitch-fill-read-only)';
|
|
100
106
|
exports['component-button-action-border-default'] = 'var(--ffe-color-component-button-action-border-default)';
|
|
101
107
|
exports['component-button-action-border-hover'] = 'var(--ffe-color-component-button-action-border-hover)';
|
|
102
108
|
exports['component-button-action-border-pressed'] = 'var(--ffe-color-component-button-action-border-pressed)';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sb1/ffe-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "100.0.3",
|
|
4
4
|
"description": "Rammeverk for Felles Front End",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SpareBank 1",
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
"lib",
|
|
10
10
|
"es",
|
|
11
11
|
"less",
|
|
12
|
-
"css"
|
|
12
|
+
"css",
|
|
13
|
+
"scripts",
|
|
14
|
+
"tokens"
|
|
13
15
|
],
|
|
14
16
|
"main": "lib/index.js",
|
|
15
17
|
"module": "es/index.js",
|
|
@@ -35,7 +37,7 @@
|
|
|
35
37
|
"build-colors": "./scripts/build-colors.cjs"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
38
|
-
"@sb1/ffe-buildtool": "^0.
|
|
40
|
+
"@sb1/ffe-buildtool": "^100.0.3",
|
|
39
41
|
"case": "^1.5.5",
|
|
40
42
|
"less": "^4.1.2",
|
|
41
43
|
"postcss": "^8.3.6"
|
|
@@ -43,5 +45,5 @@
|
|
|
43
45
|
"publishConfig": {
|
|
44
46
|
"access": "public"
|
|
45
47
|
},
|
|
46
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "8b55768332b15f6ac19ddde8e17edbbcfff2be8c"
|
|
47
49
|
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { buildAndroidColors } = require('./mobile/android.cjs');
|
|
4
|
+
const { buildIosColors } = require('./mobile/ios.cjs');
|
|
5
|
+
const { buildWebColors } = require('./web/web.cjs');
|
|
6
|
+
const { buildJSONColors } = require('./json/json.cjs');
|
|
7
|
+
|
|
8
|
+
const tokensPath = '../../tokens';
|
|
9
|
+
const files = {
|
|
10
|
+
primitive: '01 Primitive.value.json',
|
|
11
|
+
semanticLight: '02 Semantic.Light.json',
|
|
12
|
+
semanticDark: '02 Semantic.Dark.json',
|
|
13
|
+
context: '03 Context.Default.json',
|
|
14
|
+
contextAccent: '03 Context.Accent.json',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function filePath(filename) {
|
|
18
|
+
return path.resolve(__dirname, tokensPath, filename);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function loadColorsFromTokens(fileName, referenceDict) {
|
|
22
|
+
const colorDict = {};
|
|
23
|
+
const jsonContent = JSON.parse(
|
|
24
|
+
fs
|
|
25
|
+
.readFileSync(filePath(fileName), 'utf8')
|
|
26
|
+
.replaceAll('-', '.')
|
|
27
|
+
.toLowerCase(),
|
|
28
|
+
);
|
|
29
|
+
const processColorTokens = (obj, prefix = '') => {
|
|
30
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
31
|
+
if (value.$type === 'color') {
|
|
32
|
+
const cssVarName = `${prefix}${key}`;
|
|
33
|
+
if (!referenceDict) {
|
|
34
|
+
colorDict[cssVarName] = value.$value;
|
|
35
|
+
} else {
|
|
36
|
+
const colorValue = referenceDict[value.$value.slice(1, -1)];
|
|
37
|
+
if (!colorValue) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`In file ${fileName} .Color value (${colorValue}) for ${cssVarName} is missing in the reference dictionary.`,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
colorDict[cssVarName] = colorValue;
|
|
43
|
+
}
|
|
44
|
+
} else if (typeof value === 'object') {
|
|
45
|
+
processColorTokens(value, `${prefix}${key}.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
processColorTokens(jsonContent);
|
|
50
|
+
return colorDict;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function buildColorDict() {
|
|
54
|
+
const primitiveColors = loadColorsFromTokens(files.primitive);
|
|
55
|
+
const semanticLightColors = loadColorsFromTokens(
|
|
56
|
+
files.semanticLight,
|
|
57
|
+
primitiveColors,
|
|
58
|
+
);
|
|
59
|
+
const semanticDarkColors = loadColorsFromTokens(
|
|
60
|
+
files.semanticDark,
|
|
61
|
+
primitiveColors,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
light: loadColorsFromTokens(files.context, semanticLightColors),
|
|
66
|
+
dark: loadColorsFromTokens(files.context, semanticDarkColors),
|
|
67
|
+
lightAccent: loadColorsFromTokens(
|
|
68
|
+
files.contextAccent,
|
|
69
|
+
semanticLightColors,
|
|
70
|
+
),
|
|
71
|
+
darkAccent: loadColorsFromTokens(
|
|
72
|
+
files.contextAccent,
|
|
73
|
+
semanticDarkColors,
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function buildColors(platforms, iosPaths, androidPaths, jsonPaths, webPaths) {
|
|
79
|
+
console.log(platforms, iosPaths, androidPaths);
|
|
80
|
+
if (!platforms || (!androidPaths && !iosPaths && !jsonPaths && !webPaths)) {
|
|
81
|
+
console.error('Platform and path arguments are required.');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (
|
|
85
|
+
!platforms.includes('android') &&
|
|
86
|
+
!platforms.includes('ios') &&
|
|
87
|
+
!platforms.includes('json') &&
|
|
88
|
+
!platforms.includes('web')
|
|
89
|
+
) {
|
|
90
|
+
console.error(
|
|
91
|
+
"Platform must include 'android', 'ios', 'json, or 'web'.",
|
|
92
|
+
);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const colorDict = buildColorDict();
|
|
97
|
+
if (platforms.includes('android')) {
|
|
98
|
+
buildAndroidColors(androidPaths, colorDict);
|
|
99
|
+
}
|
|
100
|
+
if (platforms.includes('ios')) {
|
|
101
|
+
buildIosColors(iosPaths, colorDict);
|
|
102
|
+
}
|
|
103
|
+
if (platforms.includes('web')) {
|
|
104
|
+
buildWebColors(webPaths, colorDict);
|
|
105
|
+
}
|
|
106
|
+
if (platforms.includes('json')) {
|
|
107
|
+
buildJSONColors(jsonPaths, colorDict);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = {
|
|
112
|
+
loadColorsFromTokens,
|
|
113
|
+
buildColorDict,
|
|
114
|
+
buildColors,
|
|
115
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { writeToFile } = require('../../utils.cjs');
|
|
3
|
+
|
|
4
|
+
function buildJSONColors(paths, colors) {
|
|
5
|
+
paths.forEach(path => {
|
|
6
|
+
writeToFile(path + '/colors-semantic.json')(
|
|
7
|
+
JSON.stringify(colors, null, 2),
|
|
8
|
+
);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = { buildJSONColors };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { writeToFile } = require('../../utils.cjs');
|
|
3
|
+
|
|
4
|
+
const removeHash = value => (value.startsWith('#') ? value.slice(1) : value);
|
|
5
|
+
const cssHexToAndroidHex = str => str.slice(-2) + str.slice(0, -2);
|
|
6
|
+
|
|
7
|
+
function transformToAndroidHex(value) {
|
|
8
|
+
value = removeHash(value).toUpperCase();
|
|
9
|
+
if (value.length === 6) {
|
|
10
|
+
return `0xFF${value}`;
|
|
11
|
+
} else if (value.length === 8) {
|
|
12
|
+
return `0x${cssHexToAndroidHex(value)}`;
|
|
13
|
+
} else {
|
|
14
|
+
throw new Error(
|
|
15
|
+
`Invalid color value: ${value}. Expected 6 or 8 characters (with or without #).`,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function transformToAndroidColorName(name) {
|
|
21
|
+
return name
|
|
22
|
+
.split('.')
|
|
23
|
+
.map((part, idx) =>
|
|
24
|
+
idx === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1),
|
|
25
|
+
)
|
|
26
|
+
.join('');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function generateAndroidColorFileContent(colors) {
|
|
30
|
+
return `
|
|
31
|
+
/* Generated from Figma tokens */
|
|
32
|
+
/* Dokumentasjon på: https://sparebank1.github.io/designsystem/?path=/docs/design-farger-native--docs */
|
|
33
|
+
/* Fargene er bygget fra FFE Core versjon: ${require('../../../package.json').version} */
|
|
34
|
+
|
|
35
|
+
object Colors {
|
|
36
|
+
|
|
37
|
+
object LightDefault {
|
|
38
|
+
${Object.entries(colors.light)
|
|
39
|
+
.map(
|
|
40
|
+
([name, value]) =>
|
|
41
|
+
`val ${transformToAndroidColorName(
|
|
42
|
+
name,
|
|
43
|
+
)} = Color(${transformToAndroidHex(value)})`,
|
|
44
|
+
)
|
|
45
|
+
.join('\n')}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
object DarkDefault {
|
|
49
|
+
${Object.entries(colors.dark)
|
|
50
|
+
.map(
|
|
51
|
+
([name, value]) =>
|
|
52
|
+
`val ${transformToAndroidColorName(
|
|
53
|
+
name,
|
|
54
|
+
)} = Color(${transformToAndroidHex(value)})`,
|
|
55
|
+
)
|
|
56
|
+
.join('\n')}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
object LightAccent {
|
|
60
|
+
${Object.entries(colors.lightAccent)
|
|
61
|
+
.map(
|
|
62
|
+
([name, value]) =>
|
|
63
|
+
`val ${transformToAndroidColorName(
|
|
64
|
+
name,
|
|
65
|
+
)} = Color(${transformToAndroidHex(value)})`,
|
|
66
|
+
)
|
|
67
|
+
.join('\n')}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
object DarkAccent {
|
|
71
|
+
${Object.entries(colors.darkAccent)
|
|
72
|
+
.map(
|
|
73
|
+
([name, value]) =>
|
|
74
|
+
`\t\tval ${transformToAndroidColorName(
|
|
75
|
+
name,
|
|
76
|
+
)} = Color(${transformToAndroidHex(value)})`,
|
|
77
|
+
)
|
|
78
|
+
.join('\n')}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function buildAndroidColors(paths, colors) {
|
|
87
|
+
paths.forEach(path => {
|
|
88
|
+
writeToFile(path + '/Colors.kt')(
|
|
89
|
+
generateAndroidColorFileContent(colors),
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
buildAndroidColors,
|
|
96
|
+
generateAndroidColorFileContent,
|
|
97
|
+
transformToAndroidHex,
|
|
98
|
+
transformToAndroidColorName,
|
|
99
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const mockWrite = jest.fn();
|
|
2
|
+
const mockWriteToFile = jest.fn(() => mockWrite);
|
|
3
|
+
|
|
4
|
+
jest.mock("../../utils.cjs", () => ({
|
|
5
|
+
writeToFile: mockWriteToFile,
|
|
6
|
+
}));
|
|
7
|
+
|
|
8
|
+
const android = require("./android.cjs");
|
|
9
|
+
|
|
10
|
+
describe("android.cjs", () => {
|
|
11
|
+
describe("transformToAndroidHex", () => {
|
|
12
|
+
it("should convert #hex to C0xFF... (uppercase)", () => {
|
|
13
|
+
expect(android.transformToAndroidHex("#123abc")).toBe("C0xFF123ABC");
|
|
14
|
+
expect(android.transformToAndroidHex("#ABCDEF")).toBe("C0xFFABCDEF");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should convert 0x hex to uppercase", () => {
|
|
18
|
+
expect(android.transformToAndroidHex("0xFFAABBCC")).toBe("0XFFAABBCC");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should throw on invalid format", () => {
|
|
22
|
+
expect(() => android.transformToAndroidHex("red")).toThrow(
|
|
23
|
+
"Invalid color format"
|
|
24
|
+
);
|
|
25
|
+
expect(() => android.transformToAndroidHex("123456")).toThrow(
|
|
26
|
+
"Invalid color format"
|
|
27
|
+
);
|
|
28
|
+
expect(() => android.transformToAndroidHex("")).toThrow(
|
|
29
|
+
"Invalid color format"
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("transformToAndroidColorName", () => {
|
|
35
|
+
it("should convert dot notation to camelCase", () => {
|
|
36
|
+
expect(android.transformToAndroidColorName("primary.color")).toBe(
|
|
37
|
+
"primaryColor"
|
|
38
|
+
);
|
|
39
|
+
expect(android.transformToAndroidColorName("a.b.c")).toBe("aBC");
|
|
40
|
+
expect(android.transformToAndroidColorName("single")).toBe("single");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should handle empty string", () => {
|
|
44
|
+
expect(android.transformToAndroidColorName("")).toBe("");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("generateAndroidColorFileContent", () => {
|
|
49
|
+
it("should generate Kotlin color file content", () => {
|
|
50
|
+
const colors = {
|
|
51
|
+
"primary.color": "#123456",
|
|
52
|
+
"secondary.color": "#abcdef",
|
|
53
|
+
};
|
|
54
|
+
const content = android.generateAndroidColorFileContent(colors);
|
|
55
|
+
expect(content).toContain("val primaryColor = Color(C0xFF123456)");
|
|
56
|
+
expect(content).toContain("val secondaryColor = Color(C0xFFABCDEF)");
|
|
57
|
+
expect(content).toContain(
|
|
58
|
+
"package com.<domain_name>.<app_name>.ui.theme"
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should throw if color value is invalid", () => {
|
|
63
|
+
const colors = { "bad.color": "notacolor" };
|
|
64
|
+
expect(() => android.generateAndroidColorFileContent(colors)).toThrow(
|
|
65
|
+
"Invalid color format"
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe("buildAndroidColors", () => {
|
|
71
|
+
it("should call writeToFile for each color variant", () => {
|
|
72
|
+
const paths = ["/tmp/test"];
|
|
73
|
+
const colors = {
|
|
74
|
+
light: { "a.b": "#111111" },
|
|
75
|
+
dark: { "a.b": "#222222" },
|
|
76
|
+
lightAccent: { "a.b": "#333333" },
|
|
77
|
+
darkAccent: { "a.b": "#444444" },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
android.buildAndroidColors(paths, colors);
|
|
81
|
+
|
|
82
|
+
expect(mockWriteToFile).toHaveBeenCalledTimes(4);
|
|
83
|
+
expect(mockWriteToFile).toHaveBeenCalledWith(
|
|
84
|
+
"/tmp/test/ColorsDefaultLight.kt"
|
|
85
|
+
);
|
|
86
|
+
expect(mockWriteToFile).toHaveBeenCalledWith(
|
|
87
|
+
"/tmp/test/ColorsDefaultDark.kt"
|
|
88
|
+
);
|
|
89
|
+
expect(mockWriteToFile).toHaveBeenCalledWith(
|
|
90
|
+
"/tmp/test/ColorsAccentLight.kt"
|
|
91
|
+
);
|
|
92
|
+
expect(mockWriteToFile).toHaveBeenCalledWith(
|
|
93
|
+
"/tmp/test/ColorsAccentDark.kt"
|
|
94
|
+
);
|
|
95
|
+
expect(mockWrite).toHaveBeenCalledTimes(4);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { writeToFile } = require('../../utils.cjs');
|
|
3
|
+
|
|
4
|
+
function buildContents(paths) {
|
|
5
|
+
paths.forEach(path => {
|
|
6
|
+
writeToFile(path + '/SemanticColors.xcassets/Contents.json')(
|
|
7
|
+
`{
|
|
8
|
+
"info" : {
|
|
9
|
+
"author" : "xcode",
|
|
10
|
+
"version" : 1
|
|
11
|
+
}
|
|
12
|
+
}`,
|
|
13
|
+
);
|
|
14
|
+
writeToFile(path + '/SemanticColors.xcassets/README.md')(
|
|
15
|
+
`# Semantic Colors
|
|
16
|
+
|
|
17
|
+
Fargene er bygget fra FFE Core versjon: ${require('../../../package.json').version}
|
|
18
|
+
|
|
19
|
+
Dokumentasjon på: https://sparebank1.github.io/designsystem/?path=/docs/design-farger-native--docs
|
|
20
|
+
`,
|
|
21
|
+
);
|
|
22
|
+
writeToFile(path + '/SemanticColors.xcassets/default/Contents.json')(
|
|
23
|
+
`{
|
|
24
|
+
"info" : {
|
|
25
|
+
"author" : "xcode",
|
|
26
|
+
"version" : 1
|
|
27
|
+
}
|
|
28
|
+
}`,
|
|
29
|
+
);
|
|
30
|
+
writeToFile(path + '/SemanticColors.xcassets/accent/Contents.json')(
|
|
31
|
+
`{
|
|
32
|
+
"info" : {
|
|
33
|
+
"author" : "xcode",
|
|
34
|
+
"version" : 1
|
|
35
|
+
}
|
|
36
|
+
}`,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildSRGBComponentsFromHex(hex) {
|
|
42
|
+
// Remove # if present and convert to lowercase
|
|
43
|
+
const cleanHex = hex.replace('#', '').toLowerCase();
|
|
44
|
+
|
|
45
|
+
let r,
|
|
46
|
+
g,
|
|
47
|
+
b,
|
|
48
|
+
a = 255; // Default alpha to 255 (fully opaque)
|
|
49
|
+
|
|
50
|
+
if (cleanHex.length === 3) {
|
|
51
|
+
// RGB format: aaa -> aaaaaa
|
|
52
|
+
r = parseInt(cleanHex[0] + cleanHex[0], 16);
|
|
53
|
+
g = parseInt(cleanHex[1] + cleanHex[1], 16);
|
|
54
|
+
b = parseInt(cleanHex[2] + cleanHex[2], 16);
|
|
55
|
+
} else if (cleanHex.length === 4) {
|
|
56
|
+
// RGBA format: aaaf -> aaaaafff
|
|
57
|
+
r = parseInt(cleanHex[0] + cleanHex[0], 16);
|
|
58
|
+
g = parseInt(cleanHex[1] + cleanHex[1], 16);
|
|
59
|
+
b = parseInt(cleanHex[2] + cleanHex[2], 16);
|
|
60
|
+
a = parseInt(cleanHex[3] + cleanHex[3], 16);
|
|
61
|
+
} else if (cleanHex.length === 6) {
|
|
62
|
+
// RRGGBB format: aaaaaa
|
|
63
|
+
r = parseInt(cleanHex.slice(0, 2), 16);
|
|
64
|
+
g = parseInt(cleanHex.slice(2, 4), 16);
|
|
65
|
+
b = parseInt(cleanHex.slice(4, 6), 16);
|
|
66
|
+
} else if (cleanHex.length === 8) {
|
|
67
|
+
// RRGGBBAA format: aaaaaaff
|
|
68
|
+
r = parseInt(cleanHex.slice(0, 2), 16);
|
|
69
|
+
g = parseInt(cleanHex.slice(2, 4), 16);
|
|
70
|
+
b = parseInt(cleanHex.slice(4, 6), 16);
|
|
71
|
+
a = parseInt(cleanHex.slice(6, 8), 16);
|
|
72
|
+
} else {
|
|
73
|
+
throw new Error(`Invalid hex color format: ${hex}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Convert to 0-1 range and format to 3 decimal places
|
|
77
|
+
return `{
|
|
78
|
+
"alpha": "${(a / 255).toFixed(3)}",
|
|
79
|
+
"blue": "${(b / 255).toFixed(3)}",
|
|
80
|
+
"green": "${(g / 255).toFixed(3)}",
|
|
81
|
+
"red": "${(r / 255).toFixed(3)}"
|
|
82
|
+
}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function colorNameToFolderName(name, prefix = '') {
|
|
86
|
+
const str = prefix ? prefix + '.' : '';
|
|
87
|
+
const parts = (str + name).split('.').filter(part => part !== 'color'); // Remove 'color' prefix if present
|
|
88
|
+
|
|
89
|
+
if (parts.length === 0) return '.colorset';
|
|
90
|
+
|
|
91
|
+
// First part: lowercase first letter, rest unchanged
|
|
92
|
+
const first = parts[0].charAt(0).toLowerCase() + parts[0].slice(1);
|
|
93
|
+
|
|
94
|
+
// Remaining parts: uppercase first letter, rest unchanged
|
|
95
|
+
const rest = parts
|
|
96
|
+
.slice(1)
|
|
97
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1));
|
|
98
|
+
|
|
99
|
+
return [first, ...rest].join('') + '.colorset';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function buildColorFileContents(
|
|
103
|
+
path,
|
|
104
|
+
name,
|
|
105
|
+
light,
|
|
106
|
+
lightAccent,
|
|
107
|
+
dark,
|
|
108
|
+
darkAccent,
|
|
109
|
+
) {
|
|
110
|
+
writeToFile(
|
|
111
|
+
path +
|
|
112
|
+
'/SemanticColors.xcassets/default/' +
|
|
113
|
+
colorNameToFolderName(name) +
|
|
114
|
+
'/Contents.json',
|
|
115
|
+
)(
|
|
116
|
+
`{
|
|
117
|
+
"colors" : [
|
|
118
|
+
{
|
|
119
|
+
"color" : {
|
|
120
|
+
"color-space" : "srgb",
|
|
121
|
+
"components" : ${buildSRGBComponentsFromHex(light)}
|
|
122
|
+
},
|
|
123
|
+
"idiom" : "universal"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"appearances" : [
|
|
127
|
+
{
|
|
128
|
+
"appearance" : "luminosity",
|
|
129
|
+
"value" : "dark"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"color" : {
|
|
133
|
+
"color-space" : "srgb",
|
|
134
|
+
"components" : ${buildSRGBComponentsFromHex(dark)}
|
|
135
|
+
},
|
|
136
|
+
"idiom" : "universal"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"info" : {
|
|
140
|
+
"author" : "xcode",
|
|
141
|
+
"version" : 1
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
`,
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
writeToFile(
|
|
148
|
+
path +
|
|
149
|
+
'/SemanticColors.xcassets/accent/' +
|
|
150
|
+
colorNameToFolderName(name, 'accent') +
|
|
151
|
+
'/Contents.json',
|
|
152
|
+
)(
|
|
153
|
+
`{
|
|
154
|
+
"colors" : [
|
|
155
|
+
{
|
|
156
|
+
"color" : {
|
|
157
|
+
"color-space" : "srgb",
|
|
158
|
+
"components" : ${buildSRGBComponentsFromHex(lightAccent)}
|
|
159
|
+
},
|
|
160
|
+
"idiom" : "universal"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"appearances" : [
|
|
164
|
+
{
|
|
165
|
+
"appearance" : "luminosity",
|
|
166
|
+
"value" : "dark"
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
"color" : {
|
|
170
|
+
"color-space" : "srgb",
|
|
171
|
+
"components" : ${buildSRGBComponentsFromHex(darkAccent)}
|
|
172
|
+
},
|
|
173
|
+
"idiom" : "universal"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"info" : {
|
|
177
|
+
"author" : "xcode",
|
|
178
|
+
"version" : 1
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function buildColorFiles(paths, colors) {
|
|
186
|
+
Object.keys(colors.light).forEach(name => {
|
|
187
|
+
paths.forEach(path => {
|
|
188
|
+
buildColorFileContents(
|
|
189
|
+
path,
|
|
190
|
+
name,
|
|
191
|
+
colors.light[name],
|
|
192
|
+
colors.lightAccent[name],
|
|
193
|
+
colors.dark[name],
|
|
194
|
+
colors.darkAccent[name],
|
|
195
|
+
);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function buildIosColors(paths, colors) {
|
|
201
|
+
buildContents(paths);
|
|
202
|
+
buildColorFiles(paths, colors);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = { buildIosColors };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { writeToFile } = require('../../utils.cjs');
|
|
3
|
+
|
|
4
|
+
function transformToCssProperty(name, value) {
|
|
5
|
+
return `--ffe-${name.replaceAll('.', '-')}: ${value};`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function generateChevronCssColorFileContent(colors) {
|
|
9
|
+
return `
|
|
10
|
+
/* Generated from Figma tokens */
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
// Chevron colors to make it work with semantic colors
|
|
15
|
+
@ffe-color-chevron-light-default: ${Object.entries(colors.light)
|
|
16
|
+
.filter(([name]) => name === 'color.foreground.default')
|
|
17
|
+
.map(([_, value]) => value)[0]
|
|
18
|
+
.substring(1)};
|
|
19
|
+
@ffe-color-chevron-dark-default: ${Object.entries(colors.lightAccent)
|
|
20
|
+
.filter(([name]) => name === 'color.foreground.default')
|
|
21
|
+
.map(([_, value]) => value)[0]
|
|
22
|
+
.substring(1)};
|
|
23
|
+
@ffe-color-chevron-light-accent: ${Object.entries(colors.dark)
|
|
24
|
+
.filter(([name]) => name === 'color.foreground.default')
|
|
25
|
+
.map(([_, value]) => value)[0]
|
|
26
|
+
.substring(1)};
|
|
27
|
+
@ffe-color-chevron-dark-accent: ${Object.entries(colors.darkAccent)
|
|
28
|
+
.filter(([name]) => name === 'color.foreground.default')
|
|
29
|
+
.map(([_, value]) => value)[0]
|
|
30
|
+
.substring(1)};
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function buildChevronCssColors(paths, colors) {
|
|
38
|
+
paths.forEach(path => {
|
|
39
|
+
const content = generateChevronCssColorFileContent(colors);
|
|
40
|
+
writeToFile(path + 'less/colors-semantic-chevron.less')(content);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { buildChevronCssColors };
|