sparkle-design-cli 1.1.2 → 1.1.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/bin/sparkle-design.js
CHANGED
|
@@ -4,33 +4,33 @@ import { generateCSS } from '../lib/generate-css.js';
|
|
|
4
4
|
|
|
5
5
|
// コマンドライン引数を解析
|
|
6
6
|
function parseArguments() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const options = {
|
|
9
|
+
configPath: null,
|
|
10
|
+
outputPath: null,
|
|
11
|
+
help: false,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < args.length; i++) {
|
|
15
|
+
const arg = args[i];
|
|
16
|
+
|
|
17
|
+
if (arg === '-h' || arg === '--help') {
|
|
18
|
+
options.help = true;
|
|
19
|
+
} else if (arg === '-c' || arg === '--config') {
|
|
20
|
+
options.configPath = args[i + 1];
|
|
21
|
+
i++; // 次の引数をスキップ
|
|
22
|
+
} else if (arg === '-o' || arg === '--output') {
|
|
23
|
+
options.outputPath = args[i + 1];
|
|
24
|
+
i++; // 次の引数をスキップ
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return options;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// ヘルプメッセージを表示
|
|
32
32
|
function showHelp() {
|
|
33
|
-
|
|
33
|
+
console.log(`
|
|
34
34
|
Sparkle Design CLI - デザインシステム CSS 生成ツール
|
|
35
35
|
|
|
36
36
|
使用方法:
|
|
@@ -79,19 +79,19 @@ Sparkle Design CLI - デザインシステム CSS 生成ツール
|
|
|
79
79
|
|
|
80
80
|
// メイン処理
|
|
81
81
|
function main() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
const options = parseArguments();
|
|
83
|
+
|
|
84
|
+
if (options.help) {
|
|
85
|
+
showHelp();
|
|
86
|
+
process.exit(0);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
generateCSS(options.configPath, options.outputPath);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error('❌ エラーが発生しました:', error.message);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
main();
|
package/lib/generate-css.js
CHANGED
|
@@ -12,174 +12,180 @@ const __dirname = path.dirname(__filename);
|
|
|
12
12
|
* sparkle.config.jsonを読み込む
|
|
13
13
|
*/
|
|
14
14
|
function loadConfig(configPath = null) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
// カスタムパスが指定されていない場合は実行場所のsparkle.config.jsonを探す
|
|
16
|
+
const defaultConfigPath = path.resolve(process.cwd(), 'sparkle.config.json');
|
|
17
|
+
const resolvedConfigPath = configPath ? path.resolve(configPath) : defaultConfigPath;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const configContent = fs.readFileSync(resolvedConfigPath, 'utf8');
|
|
21
|
+
const config = JSON.parse(configContent);
|
|
22
|
+
console.log('✅ sparkle.config.json を読み込みました:', resolvedConfigPath);
|
|
23
|
+
console.log(' 設定内容:', config);
|
|
24
|
+
return config;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error('❌ sparkle.config.json の読み込みに失敗しました:', error.message);
|
|
27
|
+
console.error('設定ファイルパス:', resolvedConfigPath);
|
|
28
|
+
console.error('設定ファイルは専用プラグインから生成するか、手動で作成してください');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* CSSテンプレートを読み込む
|
|
35
35
|
*/
|
|
36
36
|
function loadTemplate() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
const templatePath = path.join(
|
|
38
|
+
__dirname,
|
|
39
|
+
'..',
|
|
40
|
+
'templates',
|
|
41
|
+
'sparkle-variables',
|
|
42
|
+
'sparkle-design.template.css'
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const templateContent = fs.readFileSync(templatePath, 'utf8');
|
|
47
|
+
console.log('✅ CSSテンプレートを読み込みました');
|
|
48
|
+
return templateContent;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('❌ CSSテンプレートの読み込みに失敗しました:', error.message);
|
|
51
|
+
console.error('テンプレートファイルが存在することを確認してください:', templatePath);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
/**
|
|
51
57
|
* 色定義(colors.json)を読み込む
|
|
52
58
|
*/
|
|
53
59
|
function loadColors() {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
const colorsPath = path.join(__dirname, '..', 'templates', 'sparkle-variables', 'colors.json');
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const colorsContent = fs.readFileSync(colorsPath, 'utf8');
|
|
64
|
+
const colors = JSON.parse(colorsContent);
|
|
65
|
+
console.log('✅ colors.json を読み込みました');
|
|
66
|
+
return colors;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error('❌ colors.json の読み込みに失敗しました:', error.message);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
/**
|
|
68
74
|
* gray.jsonを読み込む
|
|
69
75
|
*/
|
|
70
76
|
function loadGrayMapping() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
const grayJsonPath = path.join(__dirname, '..', 'templates', 'sparkle-variables', 'gray.json');
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const grayContent = fs.readFileSync(grayJsonPath, 'utf8');
|
|
81
|
+
const grayMapping = JSON.parse(grayContent);
|
|
82
|
+
console.log('✅ gray.json を読み込みました');
|
|
83
|
+
return grayMapping;
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('❌ gray.json の読み込みに失敗しました:', error.message);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
/**
|
|
85
91
|
* radius.csvを読み込む
|
|
86
92
|
*/
|
|
87
93
|
function loadRadiusMapping() {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
94
|
+
const radiusCsvPath = path.join(__dirname, '..', 'templates', 'sparkle-variables', 'radius.csv');
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const csvContent = fs.readFileSync(radiusCsvPath, 'utf8');
|
|
98
|
+
const lines = csvContent.trim().split('\n');
|
|
99
|
+
const headers = lines[0].split(',');
|
|
100
|
+
const radiusMapping = {};
|
|
101
|
+
|
|
102
|
+
for (let i = 1; i < lines.length; i++) {
|
|
103
|
+
const values = lines[i].split(',');
|
|
104
|
+
const name = values[0];
|
|
105
|
+
radiusMapping[name] = {};
|
|
106
|
+
|
|
107
|
+
for (let j = 1; j < headers.length; j++) {
|
|
108
|
+
radiusMapping[name][headers[j]] = values[j];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log('✅ radius.csv を読み込みました');
|
|
113
|
+
return radiusMapping;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('❌ radius.csv の読み込みに失敗しました:', error.message);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
/**
|
|
115
121
|
* テンプレート変数を設定値で置換する
|
|
116
122
|
*/
|
|
117
123
|
function processTemplate(template, config, grayMapping, radiusMapping, colors) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
124
|
+
let processedCSS = template;
|
|
125
|
+
|
|
126
|
+
// 1. 色のトークンを生成して置換
|
|
127
|
+
const colorTokens = generateColorTokens(colors, grayMapping, config.primary);
|
|
128
|
+
// プレースホルダーを色のトークンで置換(改行を含む)
|
|
129
|
+
processedCSS = processedCSS.replace(/\s*\/\* \{\{COLOR_TOKENS\}\} \*\/\s*/, `\n${colorTokens}\n`);
|
|
130
|
+
|
|
131
|
+
// 2. 基本的な設定値による置換
|
|
132
|
+
Object.entries(config).forEach(([key, value]) => {
|
|
133
|
+
// 通常のプレースホルダー(CSS用 - スペースはそのまま)
|
|
134
|
+
const placeholder = `{{${key.toUpperCase().replace('-', '_')}}}`;
|
|
135
|
+
processedCSS = processedCSS.replace(new RegExp(placeholder, 'g'), value);
|
|
136
|
+
|
|
137
|
+
// フォントファミリーの場合はURL用のプレースホルダーも生成(スペースを+に置き換え)
|
|
138
|
+
if (key.toLowerCase().includes('font')) {
|
|
139
|
+
const urlPlaceholder = `{{${key.toUpperCase().replace('-', '_')}_URL}}`;
|
|
140
|
+
const urlValue = value.replace(/\s+/g, '+');
|
|
141
|
+
processedCSS = processedCSS.replace(new RegExp(urlPlaceholder, 'g'), urlValue);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// 3. Radiusの一括置換
|
|
146
|
+
if (config.radius && radiusMapping[config.radius]) {
|
|
147
|
+
const radiusValues = radiusMapping[config.radius];
|
|
148
|
+
|
|
149
|
+
Object.entries(radiusValues).forEach(([semanticName, radiusValue]) => {
|
|
150
|
+
if (semanticName === 'round') return; // roundは特別扱い
|
|
151
|
+
|
|
152
|
+
const semanticPattern = new RegExp(
|
|
153
|
+
`--radius-${semanticName}:\\s*var\\(--radius-[^)]+\\)`,
|
|
154
|
+
'g'
|
|
155
|
+
);
|
|
156
|
+
processedCSS = processedCSS.replace(
|
|
157
|
+
semanticPattern,
|
|
158
|
+
`--radius-${semanticName}: var(--radius-${radiusValue})`
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
console.log(`✅ ${config.radius}に対応するradius設定を適用しました`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
console.log('✅ テンプレートを設定値で処理しました');
|
|
166
|
+
return processedCSS;
|
|
161
167
|
}
|
|
162
168
|
|
|
163
169
|
/**
|
|
164
170
|
* 16進数カラーをrgba形式に変換
|
|
165
171
|
*/
|
|
166
172
|
function hexToRgba(hex) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
173
|
+
// #を削除
|
|
174
|
+
hex = hex.replace('#', '');
|
|
175
|
+
|
|
176
|
+
// 3桁の場合は6桁に拡張
|
|
177
|
+
if (hex.length === 3) {
|
|
178
|
+
hex = hex
|
|
179
|
+
.split('')
|
|
180
|
+
.map((char) => char + char)
|
|
181
|
+
.join('');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
185
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
186
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
187
|
+
|
|
188
|
+
return `rgba(${r}, ${g}, ${b}, 1)`;
|
|
183
189
|
}
|
|
184
190
|
|
|
185
191
|
/**
|
|
@@ -188,28 +194,32 @@ function hexToRgba(hex) {
|
|
|
188
194
|
* @returns {string} OKLCH形式の文字列
|
|
189
195
|
*/
|
|
190
196
|
function hexToOklch(hex) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
197
|
+
// #を削除
|
|
198
|
+
const cleanHex = hex.replace('#', '');
|
|
199
|
+
|
|
200
|
+
// 3桁の場合は6桁に拡張
|
|
201
|
+
const fullHex =
|
|
202
|
+
cleanHex.length === 3
|
|
203
|
+
? cleanHex
|
|
204
|
+
.split('')
|
|
205
|
+
.map((char) => char + char)
|
|
206
|
+
.join('')
|
|
207
|
+
: cleanHex;
|
|
208
|
+
|
|
209
|
+
// culoriを使用してHEXからOKLCHに変換
|
|
210
|
+
const oklchColor = oklch(`#${fullHex}`);
|
|
211
|
+
|
|
212
|
+
if (!oklchColor) {
|
|
213
|
+
console.warn(`⚠️ 色の変換に失敗しました: ${hex}`);
|
|
214
|
+
return `oklch(0 0 0)`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 精度を調整して出力
|
|
218
|
+
const l = Math.round((oklchColor.l || 0) * 10000) / 10000;
|
|
219
|
+
const c = Math.round((oklchColor.c || 0) * 10000) / 10000;
|
|
220
|
+
const h = oklchColor.h ? Math.round(oklchColor.h * 10) / 10 : 0;
|
|
221
|
+
|
|
222
|
+
return `oklch(${l} ${c} ${h})`;
|
|
213
223
|
}
|
|
214
224
|
|
|
215
225
|
/**
|
|
@@ -220,109 +230,120 @@ function hexToOklch(hex) {
|
|
|
220
230
|
* @returns {string} 色のトークンのCSS文字列
|
|
221
231
|
*/
|
|
222
232
|
function generateColorTokens(colors, grayMapping, primaryColor) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
233
|
+
const colorTokens = [];
|
|
234
|
+
|
|
235
|
+
// 通常の色トークンを生成
|
|
236
|
+
Object.entries(colors).forEach(([colorName, colorValues]) => {
|
|
237
|
+
if (typeof colorValues === 'object' && colorValues !== null) {
|
|
238
|
+
Object.entries(colorValues).forEach(([level, hexValue]) => {
|
|
239
|
+
const oklchValue = hexToOklch(hexValue);
|
|
240
|
+
colorTokens.push(` --color-${colorName}-${level}: ${oklchValue};`);
|
|
241
|
+
});
|
|
242
|
+
} else if (typeof colorValues === 'string') {
|
|
243
|
+
// black, white, web-focusなどの単色
|
|
244
|
+
const oklchValue = hexToOklch(colorValues);
|
|
245
|
+
colorTokens.push(` --color-${colorName}: ${oklchValue};`);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// グレーの色トークンを生成(プライマリカラーに基づく)
|
|
250
|
+
if (primaryColor && grayMapping[primaryColor]) {
|
|
251
|
+
const grayColors = grayMapping[primaryColor];
|
|
252
|
+
Object.entries(grayColors).forEach(([key, hexValue]) => {
|
|
253
|
+
const grayLevel =
|
|
254
|
+
key === '0'
|
|
255
|
+
? '50'
|
|
256
|
+
: key === '1'
|
|
257
|
+
? '100'
|
|
258
|
+
: key === '2'
|
|
259
|
+
? '200'
|
|
260
|
+
: key === '3'
|
|
261
|
+
? '300'
|
|
262
|
+
: key === '4'
|
|
263
|
+
? '400'
|
|
264
|
+
: key === '5'
|
|
265
|
+
? '500'
|
|
266
|
+
: key === '6'
|
|
267
|
+
? '600'
|
|
268
|
+
: key === '7'
|
|
269
|
+
? '700'
|
|
270
|
+
: key === '8'
|
|
271
|
+
? '800'
|
|
272
|
+
: key === '9'
|
|
273
|
+
? '900'
|
|
274
|
+
: key;
|
|
275
|
+
|
|
276
|
+
const oklchValue = hexToOklch(hexValue);
|
|
277
|
+
colorTokens.push(` --color-gray-${grayLevel}: ${oklchValue};`);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return colorTokens.join('\n');
|
|
261
282
|
}
|
|
262
283
|
|
|
263
284
|
/**
|
|
264
285
|
* 生成されたCSSをファイルに書き出す
|
|
265
286
|
*/
|
|
266
287
|
function writeCSS(cssContent, outputPath = null) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
288
|
+
// カスタムパスが指定されていない場合は実行場所からsrc/appディレクトリに出力
|
|
289
|
+
const defaultOutputPath = path.resolve(process.cwd(), 'src', 'app', 'sparkle-design.css');
|
|
290
|
+
const resolvedOutputPath = outputPath ? path.resolve(outputPath) : defaultOutputPath;
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
// 出力ディレクトリが存在しない場合は作成
|
|
294
|
+
const outputDir = path.dirname(resolvedOutputPath);
|
|
295
|
+
if (!fs.existsSync(outputDir)) {
|
|
296
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
fs.writeFileSync(resolvedOutputPath, cssContent, 'utf8');
|
|
300
|
+
console.log('✅ sparkle-design.css を生成しました:', resolvedOutputPath);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
console.error('❌ CSSファイルの書き出しに失敗しました:', error.message);
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
284
305
|
}
|
|
285
306
|
|
|
286
307
|
/**
|
|
287
308
|
* メイン処理
|
|
288
309
|
*/
|
|
289
310
|
export function generateCSS(configPath = null, outputPath = null) {
|
|
290
|
-
|
|
311
|
+
console.log('🚀 Sparkle Design CSS Generator を開始します...\n');
|
|
291
312
|
|
|
292
|
-
|
|
293
|
-
|
|
313
|
+
// 1. 設定ファイルを読み込み
|
|
314
|
+
const config = loadConfig(configPath);
|
|
294
315
|
|
|
295
|
-
|
|
296
|
-
|
|
316
|
+
// 2. テンプレートを読み込み
|
|
317
|
+
const template = loadTemplate();
|
|
297
318
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
319
|
+
// 3. colors.json、gray.json、radius.csvを読み込み
|
|
320
|
+
const colors = loadColors();
|
|
321
|
+
const grayMapping = loadGrayMapping();
|
|
322
|
+
const radiusMapping = loadRadiusMapping();
|
|
302
323
|
|
|
303
|
-
|
|
304
|
-
|
|
324
|
+
// 4. テンプレートを設定値で処理
|
|
325
|
+
const processedCSS = processTemplate(template, config, grayMapping, radiusMapping, colors);
|
|
305
326
|
|
|
306
|
-
|
|
307
|
-
|
|
327
|
+
// 5. CSSファイルを書き出し
|
|
328
|
+
writeCSS(processedCSS, outputPath);
|
|
308
329
|
|
|
309
|
-
|
|
330
|
+
console.log('\n🎉 CSS生成が完了しました!');
|
|
310
331
|
}
|
|
311
332
|
|
|
312
333
|
// スクリプトが直接実行された場合のみメイン処理を実行
|
|
313
334
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
314
|
-
|
|
335
|
+
generateCSS();
|
|
315
336
|
}
|
|
316
337
|
|
|
317
338
|
export {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
339
|
+
loadConfig,
|
|
340
|
+
loadTemplate,
|
|
341
|
+
loadColors,
|
|
342
|
+
loadGrayMapping,
|
|
343
|
+
loadRadiusMapping,
|
|
344
|
+
processTemplate,
|
|
345
|
+
writeCSS,
|
|
346
|
+
hexToRgba,
|
|
347
|
+
hexToOklch,
|
|
348
|
+
generateColorTokens,
|
|
328
349
|
};
|
package/package.json
CHANGED
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
/* {{COLOR_TOKENS}} */
|
|
10
10
|
|
|
11
11
|
/* 角丸変数 */
|
|
12
|
-
--radius-none: 0;
|
|
13
|
-
--radius-xs: 0.125rem;
|
|
14
|
-
--radius-sm: 0.25rem;
|
|
15
|
-
--radius-md: 0.
|
|
16
|
-
--radius-lg: 0.
|
|
17
|
-
--radius-xl:
|
|
18
|
-
--radius-2xl:
|
|
19
|
-
--radius-3xl:
|
|
12
|
+
--radius-none: 0; /* 0px */
|
|
13
|
+
--radius-xs: 0.125rem; /* 2px */
|
|
14
|
+
--radius-sm: 0.25rem; /* 4px */
|
|
15
|
+
--radius-md: 0.375rem; /* 6px */
|
|
16
|
+
--radius-lg: 0.5rem; /* 8px */
|
|
17
|
+
--radius-xl: 0.75rem; /* 12px */
|
|
18
|
+
--radius-2xl: 1rem; /* 16px */
|
|
19
|
+
--radius-3xl: 1.5rem; /* 24px */
|
|
20
20
|
--radius-full: 9999px;
|
|
21
21
|
|
|
22
22
|
/* タイポグラフィ変数 */
|