@idealyst/theme 1.2.1 → 1.2.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/package.json +4 -1
- package/src/babel/plugin.js +21 -10
- package/src/babel/theme-analyzer.js +87 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idealyst/theme",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "Theming system for Idealyst Framework",
|
|
5
5
|
"readme": "README.md",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
"prepublishOnly": "echo 'Publishing TypeScript source directly'",
|
|
57
57
|
"publish:npm": "npm publish"
|
|
58
58
|
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@idealyst/tooling": "workspace:*"
|
|
61
|
+
},
|
|
59
62
|
"peerDependencies": {
|
|
60
63
|
"react-native-unistyles": ">=3.0.0"
|
|
61
64
|
},
|
package/src/babel/plugin.js
CHANGED
|
@@ -29,7 +29,19 @@
|
|
|
29
29
|
* }))
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
// Theme analysis is provided by @idealyst/tooling (single source of truth)
|
|
33
|
+
// This uses the TypeScript Compiler API for accurate theme extraction
|
|
34
|
+
let loadThemeKeys;
|
|
35
|
+
try {
|
|
36
|
+
// Try to load from @idealyst/tooling (TypeScript-based analyzer)
|
|
37
|
+
// This is the preferred path as it's the single source of truth
|
|
38
|
+
const tooling = require('@idealyst/tooling');
|
|
39
|
+
loadThemeKeys = tooling.loadThemeKeys;
|
|
40
|
+
} catch (e) {
|
|
41
|
+
// Fallback to local implementation if tooling can't be loaded
|
|
42
|
+
// (e.g., when TypeScript runtime is not available)
|
|
43
|
+
loadThemeKeys = require('./theme-analyzer').loadThemeKeys;
|
|
44
|
+
}
|
|
33
45
|
|
|
34
46
|
// ============================================================================
|
|
35
47
|
// Global Extension Registry - Persists across files during build
|
|
@@ -547,8 +559,7 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
547
559
|
}
|
|
548
560
|
}
|
|
549
561
|
|
|
550
|
-
//
|
|
551
|
-
console.log('[idealyst-plugin] Plugin loaded (AST-based theme analysis)');
|
|
562
|
+
// Plugin initialization logged in debug mode only
|
|
552
563
|
|
|
553
564
|
return {
|
|
554
565
|
name: 'idealyst-styles',
|
|
@@ -783,13 +794,13 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
783
794
|
const keys = loadThemeKeys(opts, rootDir, t, verboseMode);
|
|
784
795
|
const expandedVariants = [];
|
|
785
796
|
|
|
786
|
-
// Debug for View only
|
|
787
|
-
if (componentName === 'View') {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
797
|
+
// Debug for View only (verbose mode)
|
|
798
|
+
if (verboseMode && componentName === 'View') {
|
|
799
|
+
verbose(`\n========== VIEW KEYS DEBUG ==========`);
|
|
800
|
+
verbose(`rootDir: ${rootDir}`);
|
|
801
|
+
verbose(`keys.sizes.view: ${JSON.stringify(keys?.sizes?.view)}`);
|
|
802
|
+
verbose(`keys.intents: ${JSON.stringify(keys?.intents)}`);
|
|
803
|
+
verbose(`======================================\n`);
|
|
793
804
|
}
|
|
794
805
|
|
|
795
806
|
try {
|
|
@@ -252,6 +252,25 @@ function extractThemeKeysFromAST(themeFilePath, babelTypes, verboseMode) {
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Process a builder chain that ends with .build() - extracts theme keys.
|
|
257
|
+
* Can be called on any node that is a .build() call expression.
|
|
258
|
+
*/
|
|
259
|
+
function processBuilderChainNode(node) {
|
|
260
|
+
if (!t.isCallExpression(node)) return;
|
|
261
|
+
if (!t.isMemberExpression(node.callee)) return;
|
|
262
|
+
if (!t.isIdentifier(node.callee.property, { name: 'build' })) return;
|
|
263
|
+
|
|
264
|
+
const { calls, baseThemeVar } = traceBuilderChain(node);
|
|
265
|
+
|
|
266
|
+
if (baseThemeVar) {
|
|
267
|
+
log('Found fromTheme with base:', baseThemeVar);
|
|
268
|
+
analyzeBaseTheme(baseThemeVar);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
processBuilderCalls(calls);
|
|
272
|
+
}
|
|
273
|
+
|
|
255
274
|
// Second pass: find theme builder chains
|
|
256
275
|
traverse(ast, {
|
|
257
276
|
VariableDeclarator(path) {
|
|
@@ -262,14 +281,7 @@ function extractThemeKeysFromAST(themeFilePath, babelTypes, verboseMode) {
|
|
|
262
281
|
t.isMemberExpression(init.callee) &&
|
|
263
282
|
t.isIdentifier(init.callee.property, { name: 'build' })) {
|
|
264
283
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (baseThemeVar) {
|
|
268
|
-
log('Found fromTheme with base:', baseThemeVar);
|
|
269
|
-
analyzeBaseTheme(baseThemeVar);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
processBuilderCalls(calls);
|
|
284
|
+
processBuilderChainNode(init);
|
|
273
285
|
}
|
|
274
286
|
},
|
|
275
287
|
|
|
@@ -285,14 +297,62 @@ function extractThemeKeysFromAST(themeFilePath, babelTypes, verboseMode) {
|
|
|
285
297
|
t.isMemberExpression(init.callee) &&
|
|
286
298
|
t.isIdentifier(init.callee.property, { name: 'build' })) {
|
|
287
299
|
|
|
288
|
-
|
|
300
|
+
processBuilderChainNode(init);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
|
|
305
|
+
// Handle StyleSheet.configure({ themes: { light: ..., dark: ... } })
|
|
306
|
+
CallExpression(path) {
|
|
307
|
+
const { node } = path;
|
|
289
308
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
309
|
+
// Check for StyleSheet.configure(...)
|
|
310
|
+
if (!t.isMemberExpression(node.callee)) return;
|
|
311
|
+
if (!t.isIdentifier(node.callee.object, { name: 'StyleSheet' })) return;
|
|
312
|
+
if (!t.isIdentifier(node.callee.property, { name: 'configure' })) return;
|
|
294
313
|
|
|
295
|
-
|
|
314
|
+
log('Found StyleSheet.configure call');
|
|
315
|
+
|
|
316
|
+
const configArg = node.arguments[0];
|
|
317
|
+
if (!t.isObjectExpression(configArg)) return;
|
|
318
|
+
|
|
319
|
+
// Find the 'themes' property
|
|
320
|
+
for (const prop of configArg.properties) {
|
|
321
|
+
if (!t.isObjectProperty(prop)) continue;
|
|
322
|
+
|
|
323
|
+
const keyName = t.isIdentifier(prop.key) ? prop.key.name :
|
|
324
|
+
t.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
325
|
+
|
|
326
|
+
if (keyName !== 'themes') continue;
|
|
327
|
+
if (!t.isObjectExpression(prop.value)) continue;
|
|
328
|
+
|
|
329
|
+
log('Found themes object in StyleSheet.configure');
|
|
330
|
+
|
|
331
|
+
// Process each theme definition
|
|
332
|
+
for (const themeProp of prop.value.properties) {
|
|
333
|
+
if (!t.isObjectProperty(themeProp)) continue;
|
|
334
|
+
|
|
335
|
+
const themeName = t.isIdentifier(themeProp.key) ? themeProp.key.name :
|
|
336
|
+
t.isStringLiteral(themeProp.key) ? themeProp.key.value : null;
|
|
337
|
+
|
|
338
|
+
if (!themeName) continue;
|
|
339
|
+
|
|
340
|
+
const themeValue = themeProp.value;
|
|
341
|
+
log(` Processing theme '${themeName}'`);
|
|
342
|
+
|
|
343
|
+
// Case 1: Inline builder chain - fromTheme(x).build() or createTheme().build()
|
|
344
|
+
if (t.isCallExpression(themeValue) &&
|
|
345
|
+
t.isMemberExpression(themeValue.callee) &&
|
|
346
|
+
t.isIdentifier(themeValue.callee.property, { name: 'build' })) {
|
|
347
|
+
|
|
348
|
+
log(` Found inline builder chain for '${themeName}'`);
|
|
349
|
+
processBuilderChainNode(themeValue);
|
|
350
|
+
}
|
|
351
|
+
// Case 2: Variable reference - analyze the referenced variable's file
|
|
352
|
+
else if (t.isIdentifier(themeValue)) {
|
|
353
|
+
log(` Found variable reference '${themeValue.name}' for '${themeName}'`);
|
|
354
|
+
analyzeBaseTheme(themeValue.name);
|
|
355
|
+
}
|
|
296
356
|
}
|
|
297
357
|
}
|
|
298
358
|
}
|
|
@@ -325,18 +385,22 @@ function loadThemeKeys(opts, rootDir, babelTypes, verboseMode) {
|
|
|
325
385
|
? nodePath.resolve(rootDir, themePath)
|
|
326
386
|
: require.resolve(themePath, { paths: [rootDir] });
|
|
327
387
|
|
|
328
|
-
|
|
388
|
+
if (verboseMode) {
|
|
389
|
+
console.log('[idealyst-plugin] Analyzing theme file:', resolvedPath);
|
|
390
|
+
}
|
|
329
391
|
|
|
330
392
|
themeKeys = extractThemeKeysFromAST(resolvedPath, babelTypes, verboseMode);
|
|
331
393
|
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
394
|
+
// Log extracted keys in verbose mode
|
|
395
|
+
if (verboseMode) {
|
|
396
|
+
console.log('[idealyst-plugin] Extracted theme keys:');
|
|
397
|
+
console.log(' intents:', themeKeys.intents);
|
|
398
|
+
console.log(' radii:', themeKeys.radii);
|
|
399
|
+
console.log(' shadows:', themeKeys.shadows);
|
|
400
|
+
console.log(' sizes:');
|
|
401
|
+
for (const [component, sizes] of Object.entries(themeKeys.sizes)) {
|
|
402
|
+
console.log(` ${component}:`, sizes);
|
|
403
|
+
}
|
|
340
404
|
}
|
|
341
405
|
|
|
342
406
|
return themeKeys;
|