sparkle-design-cli 1.3.11 → 1.4.1
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 +59 -18
- package/bin/sparkle-design.js +17 -0
- package/lib/constants.js +20 -0
- package/lib/font-manager.js +53 -10
- package/lib/generate-css.js +91 -4
- package/package.json +1 -1
- package/templates/sparkle-variables/sparkle-design.template.css +3 -5
package/README.md
CHANGED
|
@@ -178,45 +178,86 @@ npx --yes sparkle-design-cli setup --assistant generic
|
|
|
178
178
|
|
|
179
179
|
### 設定オプション
|
|
180
180
|
|
|
181
|
+
#### Core(プラグインが出力)
|
|
182
|
+
|
|
181
183
|
- `primary`: プライマリカラー(blue, red, orange など)
|
|
182
|
-
- `font-pro`:
|
|
183
|
-
- `font-mono`:
|
|
184
|
+
- `font-pro`: プロポーショナルフォント(文字列または配列。配列の場合はフォールバックチェーンになる)
|
|
185
|
+
- `font-mono`: モノスペースフォント(文字列または配列)
|
|
184
186
|
- `radius`: 角丸設定(sm, md, lg など)
|
|
187
|
+
|
|
188
|
+
#### Core Options
|
|
189
|
+
|
|
190
|
+
- `font-pro-weights`: (オプション)プロポーショナルフォントのウェイト配列(デフォルト: `[400, 700]`)
|
|
191
|
+
- `font-mono-weights`: (オプション)モノスペースフォントのウェイト配列(デフォルト: `[400, 700]`)
|
|
185
192
|
- `source-packages`: (オプション)`@source` ディレクティブで追加スキャンする npm パッケージの配列
|
|
186
193
|
|
|
187
|
-
|
|
194
|
+
#### Custom Settings
|
|
188
195
|
|
|
189
|
-
|
|
196
|
+
- `custom-css`: (オプション)プロジェクト固有のカスタムトークン CSS ファイルのパス。`globals.css` に `@import` が自動挿入される
|
|
190
197
|
|
|
191
|
-
|
|
198
|
+
### フォントウェイトとフォールバック
|
|
199
|
+
|
|
200
|
+
`font-pro-weights` / `font-mono-weights` でフォントウェイトをカスタマイズできます。未指定時は `[400, 700]` がデフォルトです。
|
|
201
|
+
|
|
202
|
+
`font-pro` / `font-mono` に配列を指定すると、フォントフォールバックチェーンとして複数の Google Fonts import が生成されます。
|
|
192
203
|
|
|
193
204
|
```json
|
|
194
205
|
{
|
|
195
206
|
"primary": "blue",
|
|
196
|
-
"font-
|
|
197
|
-
"font-pro":
|
|
198
|
-
"
|
|
199
|
-
"
|
|
207
|
+
"font-pro": ["Montserrat", "Noto Sans JP"],
|
|
208
|
+
"font-pro-weights": [400, 500, 600, 700],
|
|
209
|
+
"font-mono": "Roboto Mono",
|
|
210
|
+
"font-mono-weights": [400, 700],
|
|
211
|
+
"radius": "md"
|
|
200
212
|
}
|
|
201
213
|
```
|
|
202
214
|
|
|
203
|
-
|
|
215
|
+
生成される CSS:
|
|
216
|
+
|
|
217
|
+
```css
|
|
218
|
+
--font-family-pro: 'Montserrat', 'Noto Sans JP', sans-serif;
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
```css
|
|
222
|
+
@import 'https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap';
|
|
223
|
+
@import 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;600;700&display=swap';
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### custom-css オプション
|
|
227
|
+
|
|
228
|
+
プロジェクト固有のカスタムトークン(Display, Heading, Body 等のタイポグラフィトークン、追加のフォントウェイト、メディアクエリなど)を `sparkle-design.css` に直接追加するのは避けてください。`generate` 実行時に上書きされます。
|
|
229
|
+
|
|
230
|
+
代わりに、カスタムトークンを別の CSS ファイルに定義し、`custom-css` で指定してください:
|
|
204
231
|
|
|
205
232
|
```json
|
|
206
233
|
{
|
|
207
|
-
"
|
|
234
|
+
"custom-css": "./src/app/custom-tokens.css"
|
|
208
235
|
}
|
|
209
236
|
```
|
|
210
237
|
|
|
211
|
-
|
|
238
|
+
CLI が `globals.css` に `@import` を自動挿入します。CLI はファイルの中身を一切触りません。
|
|
212
239
|
|
|
213
240
|
```css
|
|
214
|
-
|
|
215
|
-
/*
|
|
216
|
-
@
|
|
217
|
-
@
|
|
218
|
-
/* Sparkle Design
|
|
219
|
-
@import
|
|
241
|
+
/* globals.css に自動生成される構造 */
|
|
242
|
+
/* フォントのインポート */
|
|
243
|
+
@import '...google fonts...';
|
|
244
|
+
@import "tailwindcss";
|
|
245
|
+
/* Sparkle Design のカスタム定義 */
|
|
246
|
+
@import "./sparkle-design.css";
|
|
247
|
+
/* プロジェクト固有のカスタムトークン */
|
|
248
|
+
@import "./custom-tokens.css";
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### source-packages オプション
|
|
252
|
+
|
|
253
|
+
`@goodpatch/sparkle-design` を npm パッケージとして利用するプロジェクトでは、TailwindCSS v4 がパッケージ内のユーティリティクラスを検出できるように `@source` ディレクティブが必要です。
|
|
254
|
+
|
|
255
|
+
`source-packages` を設定すると、CLI が `globals.css` に `@source` ディレクティブを自動挿入します。`@goodpatch/sparkle-design` は常にデフォルトで含まれます。
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"source-packages": ["@scope/my-extension-design"]
|
|
260
|
+
}
|
|
220
261
|
```
|
|
221
262
|
|
|
222
263
|
> **注意**: `source-packages` を指定しない場合、`@source` ディレクティブは生成されません。
|
package/bin/sparkle-design.js
CHANGED
|
@@ -144,6 +144,23 @@ Generate options:
|
|
|
144
144
|
-c, --config <path> 設定ファイルのパス (default: ./sparkle.config.json)
|
|
145
145
|
-o, --output <path> 出力ファイルのパス (default: ./src/app/sparkle-design.css)
|
|
146
146
|
|
|
147
|
+
sparkle.config.json の設定フィールド:
|
|
148
|
+
primary プライマリカラー (blue, red, orange, green, purple, pink, yellow など)
|
|
149
|
+
font-pro プロポーショナルフォント (Google Fonts の名前)
|
|
150
|
+
配列を指定するとフォールバックチェーン
|
|
151
|
+
例: ["Montserrat", "Noto Sans JP"]
|
|
152
|
+
font-mono モノスペースフォント (Google Fonts の名前、配列も可)
|
|
153
|
+
radius 角丸設定 (none, sm, md, lg, xl, full)
|
|
154
|
+
font-pro-weights (任意) フォントウェイト配列 (default: [400, 700])
|
|
155
|
+
例: [400, 500, 600, 700]
|
|
156
|
+
font-mono-weights (任意) モノスペースフォントのウェイト配列 (default: [400, 700])
|
|
157
|
+
source-packages (任意) @source で追加スキャンする npm パッケージ名の配列
|
|
158
|
+
custom-css (任意) プロジェクト固有のカスタムトークン CSS ファイルパス
|
|
159
|
+
globals.css に @import が自動挿入される
|
|
160
|
+
|
|
161
|
+
設定ファイルは Sparkle Design Theme Settings Figma プラグインから書き出せます:
|
|
162
|
+
https://www.figma.com/community/plugin/1443500367756891364
|
|
163
|
+
|
|
147
164
|
Check options:
|
|
148
165
|
-h, --help このヘルプメッセージを表示
|
|
149
166
|
--strict 違反があれば exit code 1 で終了
|
package/lib/constants.js
CHANGED
|
@@ -37,8 +37,13 @@ export const REGEX = {
|
|
|
37
37
|
SOURCE_DIRECTIVE: /@source\s+["'][^"']*["'];?\s*\n?/g,
|
|
38
38
|
SOURCE_COMMENT: /\/\*\s*npm パッケージのコンテンツスキャン[^*]*\*\/\s*\n?/g,
|
|
39
39
|
|
|
40
|
+
// カスタムCSS関連
|
|
41
|
+
CUSTOM_CSS_IMPORT:
|
|
42
|
+
/\/\*\s*プロジェクト固有のカスタムトークン[^*]*\*\/\s*\n?|@import\s+['"][^"']*custom[^"']*['"];?\s*\n?/g,
|
|
43
|
+
|
|
40
44
|
// テンプレート関連
|
|
41
45
|
COLOR_TOKENS_PLACEHOLDER: /[ \t]*\/\* \{\{COLOR_TOKENS\}\} \*\/[ \t]*\n?/,
|
|
46
|
+
FONT_IMPORTS_PLACEHOLDER: /[ \t]*\/\* \{\{FONT_IMPORTS\}\} \*\/[ \t]*\n?/,
|
|
42
47
|
RADIUS_SEMANTIC_PATTERN: (semanticName) =>
|
|
43
48
|
new RegExp(`--radius-${semanticName}:\\s*var\\(--radius-[^)]+\\)`, 'g'),
|
|
44
49
|
};
|
|
@@ -46,6 +51,20 @@ export const REGEX = {
|
|
|
46
51
|
// テンプレートプレースホルダー
|
|
47
52
|
export const PLACEHOLDERS = {
|
|
48
53
|
COLOR_TOKENS: '{{COLOR_TOKENS}}',
|
|
54
|
+
FONT_IMPORTS: '{{FONT_IMPORTS}}',
|
|
55
|
+
FONT_FAMILY_PRO: '{{FONT_FAMILY_PRO}}',
|
|
56
|
+
FONT_FAMILY_MONO: '{{FONT_FAMILY_MONO}}',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// フォントのデフォルト設定
|
|
60
|
+
export const FONT_DEFAULTS = {
|
|
61
|
+
WEIGHTS: [400, 700],
|
|
62
|
+
MATERIAL_SYMBOLS_IMPORT:
|
|
63
|
+
"@import 'https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,0..200&display=block';",
|
|
64
|
+
GENERIC_FAMILY: {
|
|
65
|
+
pro: 'sans-serif',
|
|
66
|
+
mono: 'monospace',
|
|
67
|
+
},
|
|
49
68
|
};
|
|
50
69
|
|
|
51
70
|
// カラー変換精度
|
|
@@ -76,6 +95,7 @@ export const COMMENTS = {
|
|
|
76
95
|
SPARKLE_IMPORT: '/* Sparkle Design のカスタム定義(Tailwindの後にインポート) */',
|
|
77
96
|
TAILWIND_IMPORT: '/* Tailwindのインポート */',
|
|
78
97
|
SOURCE_DIRECTIVE: '/* npm パッケージのコンテンツスキャン(Tailwind がクラスを検出するために必要) */',
|
|
98
|
+
CUSTOM_CSS: '/* プロジェクト固有のカスタムトークン */',
|
|
79
99
|
};
|
|
80
100
|
|
|
81
101
|
// インポート文のテンプレート
|
package/lib/font-manager.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import fs from 'fs';
|
|
7
7
|
import path from 'path';
|
|
8
|
-
import { REGEX, COMMENTS, IMPORTS, MESSAGES } from './constants.js';
|
|
8
|
+
import { REGEX, COMMENTS, IMPORTS, MESSAGES, FONT_DEFAULTS } from './constants.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* sparkle-design.css からフォントの@import文を抽出する
|
|
@@ -72,18 +72,56 @@ function createSourceBlock(sourcePackages = [], nodeModulesRel = '../node_module
|
|
|
72
72
|
return [COMMENTS.SOURCE_DIRECTIVE, ...sourceLines].join('\n');
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* カスタムCSS importブロックを生成する
|
|
77
|
+
* @param {string} customCssPath custom-css ファイルの相対パス
|
|
78
|
+
* @param {string} globalsPath globals.css の絶対パス(相対パス計算用)
|
|
79
|
+
* @returns {string} カスタムCSS importブロック
|
|
80
|
+
*/
|
|
81
|
+
function createCustomCssImportBlock(customCssPath, globalsPath) {
|
|
82
|
+
if (!customCssPath) {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// custom-css パスは sparkle.config.json からの相対パス(= プロジェクトルートからの相対パス)
|
|
87
|
+
// globals.css からの相対パスに変換
|
|
88
|
+
const globalsDir = path.dirname(globalsPath);
|
|
89
|
+
const absoluteCustomPath = path.resolve(process.cwd(), customCssPath);
|
|
90
|
+
let relativePath = path.relative(globalsDir, absoluteCustomPath).split(path.sep).join('/');
|
|
91
|
+
|
|
92
|
+
// 相対パスが ./ で始まらない場合は付与
|
|
93
|
+
if (!relativePath.startsWith('.')) {
|
|
94
|
+
relativePath = `./${relativePath}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return [COMMENTS.CUSTOM_CSS, `@import "${relativePath}";`].join('\n');
|
|
98
|
+
}
|
|
99
|
+
|
|
75
100
|
/**
|
|
76
101
|
* sparkle-design.css importブロックを生成する
|
|
77
102
|
* @param {Array<string>} sourcePackages 追加パッケージ名の配列
|
|
78
103
|
* @param {string} globalsPath globals.css の絶対パス(@source パス計算用)
|
|
104
|
+
* @param {string|null} customCssPath custom-css ファイルの相対パス
|
|
79
105
|
* @returns {string} sparkle-design.css importブロック
|
|
80
106
|
*/
|
|
81
|
-
function createSparkleImportBlock(sourcePackages = [], globalsPath = null) {
|
|
82
|
-
|
|
83
|
-
|
|
107
|
+
function createSparkleImportBlock(sourcePackages = [], globalsPath = null, customCssPath = null) {
|
|
108
|
+
const parts = [''];
|
|
109
|
+
|
|
110
|
+
if (sourcePackages !== null && sourcePackages !== undefined) {
|
|
111
|
+
const nodeModulesRel = globalsPath ? resolveNodeModulesRelPath(globalsPath) : '../node_modules';
|
|
112
|
+
parts.push(createSourceBlock(sourcePackages, nodeModulesRel));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
parts.push(COMMENTS.SPARKLE_IMPORT, IMPORTS.SPARKLE_DESIGN);
|
|
116
|
+
|
|
117
|
+
// カスタムCSS import を sparkle-design.css の後に配置
|
|
118
|
+
const customBlock = createCustomCssImportBlock(customCssPath, globalsPath);
|
|
119
|
+
if (customBlock) {
|
|
120
|
+
parts.push(customBlock);
|
|
84
121
|
}
|
|
85
|
-
|
|
86
|
-
|
|
122
|
+
|
|
123
|
+
parts.push('');
|
|
124
|
+
return parts.join('\n');
|
|
87
125
|
}
|
|
88
126
|
|
|
89
127
|
/**
|
|
@@ -104,6 +142,9 @@ function removeExistingImports(globalsContent) {
|
|
|
104
142
|
// 既存のsparkle-design.css importを削除
|
|
105
143
|
cleaned = cleaned.replace(REGEX.SPARKLE_IMPORT, '');
|
|
106
144
|
|
|
145
|
+
// 既存のカスタムCSS importを削除
|
|
146
|
+
cleaned = cleaned.replace(REGEX.CUSTOM_CSS_IMPORT, '');
|
|
147
|
+
|
|
107
148
|
return cleaned;
|
|
108
149
|
}
|
|
109
150
|
|
|
@@ -159,9 +200,10 @@ function reconstructGlobalsCss(globalsContent, fontImportBlock, sparkleImportBlo
|
|
|
159
200
|
* @param {Array<string>} fontImports フォントimport文の配列
|
|
160
201
|
* @param {string} globalsPath globals.cssのパス
|
|
161
202
|
* @param {Array<string>|null} sourcePackages 追加パッケージ名の配列(null の場合は @source を生成しない)
|
|
203
|
+
* @param {string|null} customCssPath custom-css ファイルの相対パス
|
|
162
204
|
* @returns {boolean} globals.css の更新に成功した場合は true
|
|
163
205
|
*/
|
|
164
|
-
export function updateGlobalsWithFonts(fontImports, globalsPath, sourcePackages = null) {
|
|
206
|
+
export function updateGlobalsWithFonts(fontImports, globalsPath, sourcePackages = null, customCssPath = null) {
|
|
165
207
|
if (fontImports.length === 0) {
|
|
166
208
|
return false;
|
|
167
209
|
}
|
|
@@ -182,7 +224,7 @@ export function updateGlobalsWithFonts(fontImports, globalsPath, sourcePackages
|
|
|
182
224
|
|
|
183
225
|
// 4. importブロックを生成
|
|
184
226
|
const fontImportBlock = createFontImportBlock(fontImports);
|
|
185
|
-
const sparkleImportBlock = createSparkleImportBlock(sourcePackages, globalsPath);
|
|
227
|
+
const sparkleImportBlock = createSparkleImportBlock(sourcePackages, globalsPath, customCssPath);
|
|
186
228
|
|
|
187
229
|
// 5. globals.css を再構築
|
|
188
230
|
const reconstructedContent = reconstructGlobalsCss(
|
|
@@ -208,8 +250,9 @@ export function updateGlobalsWithFonts(fontImports, globalsPath, sourcePackages
|
|
|
208
250
|
* sparkle-design.css からフォントimportを抽出し、globals.css に移動する
|
|
209
251
|
* @param {string} sparkleDesignPath sparkle-design.cssのパス
|
|
210
252
|
* @param {Array<string>|null} sourcePackages 追加パッケージ名の配列(null の場合は @source を生成しない)
|
|
253
|
+
* @param {string|null} customCssPath custom-css ファイルの相対パス
|
|
211
254
|
*/
|
|
212
|
-
export function manageFontImports(sparkleDesignPath, sourcePackages = null) {
|
|
255
|
+
export function manageFontImports(sparkleDesignPath, sourcePackages = null, customCssPath = null) {
|
|
213
256
|
try {
|
|
214
257
|
// 1. globals.cssのパスを推定(sparkle-design.cssと同じディレクトリ)
|
|
215
258
|
const globalsPath = path.join(path.dirname(sparkleDesignPath), 'globals.css');
|
|
@@ -232,7 +275,7 @@ export function manageFontImports(sparkleDesignPath, sourcePackages = null) {
|
|
|
232
275
|
console.log(MESSAGES.FONT_DETECTED(fontImports.length));
|
|
233
276
|
|
|
234
277
|
// 4. globals.css にフォントimportを追加
|
|
235
|
-
const globalsUpdated = updateGlobalsWithFonts(fontImports, globalsPath, sourcePackages);
|
|
278
|
+
const globalsUpdated = updateGlobalsWithFonts(fontImports, globalsPath, sourcePackages, customCssPath);
|
|
236
279
|
|
|
237
280
|
if (!globalsUpdated) {
|
|
238
281
|
console.log(MESSAGES.FONT_REMOVE_SKIPPED);
|
package/lib/generate-css.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import fs from 'fs';
|
|
9
9
|
import path from 'path';
|
|
10
|
-
import { REGEX, PATHS, MESSAGES } from './constants.js';
|
|
10
|
+
import { REGEX, PATHS, MESSAGES, FONT_DEFAULTS } from './constants.js';
|
|
11
11
|
import {
|
|
12
12
|
loadConfig,
|
|
13
13
|
loadTemplate,
|
|
@@ -48,6 +48,71 @@ function dedupeFontImports(cssContent) {
|
|
|
48
48
|
.join('\n');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* フォント設定を正規化する(文字列 → 配列)
|
|
53
|
+
* @param {string|string[]} fontValue フォント名(文字列または配列)
|
|
54
|
+
* @returns {string[]} フォント名の配列
|
|
55
|
+
*/
|
|
56
|
+
function normalizeFontConfig(fontValue) {
|
|
57
|
+
if (Array.isArray(fontValue)) {
|
|
58
|
+
return fontValue;
|
|
59
|
+
}
|
|
60
|
+
return [fontValue];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Google Fonts の @import 行を生成する
|
|
65
|
+
* @param {string[]} fonts フォント名の配列
|
|
66
|
+
* @param {number[]} weights ウェイトの配列
|
|
67
|
+
* @returns {string[]} @import 文の配列
|
|
68
|
+
*/
|
|
69
|
+
function generateGoogleFontImports(fonts, weights) {
|
|
70
|
+
const weightsStr = weights.sort((a, b) => a - b).join(';');
|
|
71
|
+
return fonts.map(font => {
|
|
72
|
+
const urlName = font.replace(/\s+/g, '+');
|
|
73
|
+
return `@import 'https://fonts.googleapis.com/css2?family=${urlName}:wght@${weightsStr}&display=swap';`;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* フォントファミリーの CSS 値を生成する
|
|
79
|
+
* @param {string[]} fonts フォント名の配列
|
|
80
|
+
* @param {string} genericFamily ジェネリックファミリー(sans-serif / monospace)
|
|
81
|
+
* @returns {string} CSS font-family 値(例: 'Montserrat', 'Noto Sans JP', sans-serif)
|
|
82
|
+
*/
|
|
83
|
+
function generateFontFamilyValue(fonts, genericFamily) {
|
|
84
|
+
const quoted = fonts.map(f => `'${f}'`);
|
|
85
|
+
return [...quoted, genericFamily].join(', ');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* フォント import ブロック全体を生成する(Material Symbols + PRO + MONO)
|
|
90
|
+
* @param {Object} config 設定オブジェクト
|
|
91
|
+
* @returns {string} フォント import ブロック
|
|
92
|
+
*/
|
|
93
|
+
function generateFontImportsBlock(config) {
|
|
94
|
+
const proFonts = normalizeFontConfig(config['font-pro']);
|
|
95
|
+
const monoFonts = normalizeFontConfig(config['font-mono']);
|
|
96
|
+
const proWeights = config['font-pro-weights'] || FONT_DEFAULTS.WEIGHTS;
|
|
97
|
+
const monoWeights = config['font-mono-weights'] || FONT_DEFAULTS.WEIGHTS;
|
|
98
|
+
|
|
99
|
+
const imports = [
|
|
100
|
+
FONT_DEFAULTS.MATERIAL_SYMBOLS_IMPORT,
|
|
101
|
+
...generateGoogleFontImports(proFonts, proWeights),
|
|
102
|
+
...generateGoogleFontImports(monoFonts, monoWeights),
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
// 重複排除(font-pro と font-mono が同じフォントでウェイトも同じ場合)
|
|
106
|
+
const seen = new Set();
|
|
107
|
+
const deduped = imports.filter(line => {
|
|
108
|
+
if (seen.has(line)) return false;
|
|
109
|
+
seen.add(line);
|
|
110
|
+
return true;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return deduped.join('\n');
|
|
114
|
+
}
|
|
115
|
+
|
|
51
116
|
/**
|
|
52
117
|
* テンプレート変数を設定値で置換する
|
|
53
118
|
* @param {string} template CSSテンプレート
|
|
@@ -65,8 +130,24 @@ function processTemplate(template, config, grayMapping, radiusMapping, colors) {
|
|
|
65
130
|
// プレースホルダーを色のトークンで置換(改行を含む)
|
|
66
131
|
processedCSS = processedCSS.replace(REGEX.COLOR_TOKENS_PLACEHOLDER, `${colorTokens}\n`);
|
|
67
132
|
|
|
68
|
-
// 2.
|
|
133
|
+
// 2. フォント import ブロックを生成して置換
|
|
134
|
+
const fontImportsBlock = generateFontImportsBlock(config);
|
|
135
|
+
processedCSS = processedCSS.replace(REGEX.FONT_IMPORTS_PLACEHOLDER, `${fontImportsBlock}\n`);
|
|
136
|
+
|
|
137
|
+
// 3. フォントファミリー CSS 値を生成して置換
|
|
138
|
+
const proFonts = normalizeFontConfig(config['font-pro']);
|
|
139
|
+
const monoFonts = normalizeFontConfig(config['font-mono']);
|
|
140
|
+
const proFamilyValue = generateFontFamilyValue(proFonts, FONT_DEFAULTS.GENERIC_FAMILY.pro);
|
|
141
|
+
const monoFamilyValue = generateFontFamilyValue(monoFonts, FONT_DEFAULTS.GENERIC_FAMILY.mono);
|
|
142
|
+
processedCSS = processedCSS.replace(/\{\{FONT_FAMILY_PRO\}\}/g, proFamilyValue);
|
|
143
|
+
processedCSS = processedCSS.replace(/\{\{FONT_FAMILY_MONO\}\}/g, monoFamilyValue);
|
|
144
|
+
|
|
145
|
+
// 4. 基本的な設定値による置換(font-pro / font-mono の配列以外)
|
|
69
146
|
Object.entries(config).forEach(([key, value]) => {
|
|
147
|
+
// 配列や font-*-weights はスキップ
|
|
148
|
+
if (Array.isArray(value) || key.endsWith('-weights') || key === 'custom-css') {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
70
151
|
// 通常のプレースホルダー(CSS用 - スペースはそのまま)
|
|
71
152
|
const placeholder = `{{${key.toUpperCase().replace('-', '_')}}}`;
|
|
72
153
|
processedCSS = processedCSS.replace(new RegExp(placeholder, 'g'), value);
|
|
@@ -79,7 +160,7 @@ function processTemplate(template, config, grayMapping, radiusMapping, colors) {
|
|
|
79
160
|
}
|
|
80
161
|
});
|
|
81
162
|
|
|
82
|
-
//
|
|
163
|
+
// 6. Radiusの一括置換
|
|
83
164
|
if (config.radius && radiusMapping[config.radius]) {
|
|
84
165
|
const radiusValues = radiusMapping[config.radius];
|
|
85
166
|
|
|
@@ -165,7 +246,8 @@ export function generateCSS(configPath = null, outputPath = null) {
|
|
|
165
246
|
// 6. フォント管理の自動処理を実行
|
|
166
247
|
console.log(MESSAGES.FONT_MANAGEMENT_START);
|
|
167
248
|
const sourcePackages = 'source-packages' in config ? (config['source-packages'] || []) : null;
|
|
168
|
-
|
|
249
|
+
const customCssPath = config['custom-css'] || null;
|
|
250
|
+
manageFontImports(resolvedOutputPath, sourcePackages, customCssPath);
|
|
169
251
|
|
|
170
252
|
console.log(MESSAGES.SUCCESS);
|
|
171
253
|
}
|
|
@@ -191,6 +273,11 @@ export {
|
|
|
191
273
|
hexToOklch,
|
|
192
274
|
generateColorTokens,
|
|
193
275
|
dedupeFontImports,
|
|
276
|
+
// フォント処理
|
|
277
|
+
normalizeFontConfig,
|
|
278
|
+
generateGoogleFontImports,
|
|
279
|
+
generateFontFamilyValue,
|
|
280
|
+
generateFontImportsBlock,
|
|
194
281
|
// フォント管理
|
|
195
282
|
extractFontImports,
|
|
196
283
|
removeFontImportsFromCSS,
|
package/package.json
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/* フォントのインポート */
|
|
2
|
-
|
|
3
|
-
@import 'https://fonts.googleapis.com/css2?family={{FONT_PRO_URL}}:wght@400;700&display=swap';
|
|
4
|
-
@import 'https://fonts.googleapis.com/css2?family={{FONT_MONO_URL}}:wght@400;700&display=swap';
|
|
2
|
+
/* {{FONT_IMPORTS}} */
|
|
5
3
|
|
|
6
4
|
/* Primitive Tokens */
|
|
7
5
|
:root {
|
|
@@ -21,8 +19,8 @@
|
|
|
21
19
|
|
|
22
20
|
/* タイポグラフィ変数 */
|
|
23
21
|
/* フォントファミリー */
|
|
24
|
-
--font-family-pro:
|
|
25
|
-
--font-family-mono:
|
|
22
|
+
--font-family-pro: {{FONT_FAMILY_PRO}};
|
|
23
|
+
--font-family-mono: {{FONT_FAMILY_MONO}};
|
|
26
24
|
--font-family-icon: 'Material Symbols Rounded';
|
|
27
25
|
|
|
28
26
|
/* フォントサイズ */
|