@idealyst/theme 1.2.104 → 1.2.106
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 +2 -2
- package/src/babel/plugin.js +268 -18
- package/src/styleBuilder.ts +24 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idealyst/theme",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.106",
|
|
4
4
|
"description": "Theming system for Idealyst Framework",
|
|
5
5
|
"readme": "README.md",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"publish:npm": "npm publish"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@idealyst/tooling": "^1.2.
|
|
66
|
+
"@idealyst/tooling": "^1.2.106"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"react-native-unistyles": ">=3.0.0"
|
package/src/babel/plugin.js
CHANGED
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
* }))
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
+
const fs = require('fs');
|
|
33
|
+
const nodePath = require('path');
|
|
34
|
+
const crypto = require('crypto');
|
|
35
|
+
|
|
32
36
|
// Theme analysis is provided by @idealyst/tooling (single source of truth)
|
|
33
37
|
// This uses the TypeScript Compiler API for accurate theme extraction
|
|
34
38
|
let loadThemeKeys;
|
|
@@ -48,6 +52,7 @@ try {
|
|
|
48
52
|
// ============================================================================
|
|
49
53
|
|
|
50
54
|
// Map of componentName -> { base: AST | null, extensions: AST[], overrides: AST | null }
|
|
55
|
+
// In-memory registry still used as fast path within a single worker
|
|
51
56
|
const styleRegistry = {};
|
|
52
57
|
|
|
53
58
|
function getOrCreateEntry(componentName) {
|
|
@@ -62,6 +67,212 @@ function getOrCreateEntry(componentName) {
|
|
|
62
67
|
return styleRegistry[componentName];
|
|
63
68
|
}
|
|
64
69
|
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// File-Based Extension Cache - Cross-worker persistence
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// When bundlers use multiple workers (Metro, Vite), each worker has its own
|
|
74
|
+
// copy of the in-memory styleRegistry. The file-based cache ensures extensions
|
|
75
|
+
// registered in any worker are visible to all workers processing defineStyle.
|
|
76
|
+
|
|
77
|
+
let _cacheDir = null;
|
|
78
|
+
let _cacheInitialized = false;
|
|
79
|
+
// Track hashes we've already written in this worker to avoid re-reading our own
|
|
80
|
+
const _writtenHashes = new Set();
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get or create the cache directory for style extensions.
|
|
84
|
+
* Uses node_modules/.cache/idealyst-styles/ by convention.
|
|
85
|
+
*/
|
|
86
|
+
function getCacheDir(rootDir) {
|
|
87
|
+
if (_cacheDir) return _cacheDir;
|
|
88
|
+
|
|
89
|
+
// Walk up from rootDir to find the nearest node_modules
|
|
90
|
+
let dir = rootDir;
|
|
91
|
+
while (dir !== nodePath.dirname(dir)) {
|
|
92
|
+
const nmPath = nodePath.join(dir, 'node_modules');
|
|
93
|
+
if (fs.existsSync(nmPath)) {
|
|
94
|
+
_cacheDir = nodePath.join(nmPath, '.cache', 'idealyst-styles');
|
|
95
|
+
return _cacheDir;
|
|
96
|
+
}
|
|
97
|
+
dir = nodePath.dirname(dir);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Fallback: use rootDir directly
|
|
101
|
+
_cacheDir = nodePath.join(rootDir, 'node_modules', '.cache', 'idealyst-styles');
|
|
102
|
+
return _cacheDir;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Initialize the cache directory. Clears stale data from previous builds.
|
|
107
|
+
* Uses a build marker (PID + timestamp) to detect new build processes.
|
|
108
|
+
*/
|
|
109
|
+
function initCache(rootDir) {
|
|
110
|
+
if (_cacheInitialized) return;
|
|
111
|
+
_cacheInitialized = true;
|
|
112
|
+
|
|
113
|
+
const cacheDir = getCacheDir(rootDir);
|
|
114
|
+
const markerPath = nodePath.join(cacheDir, '.build-marker');
|
|
115
|
+
|
|
116
|
+
// Create cache dir if needed
|
|
117
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
118
|
+
|
|
119
|
+
// Check if this is a new build
|
|
120
|
+
const currentMarker = `${process.pid}`;
|
|
121
|
+
let existingMarker = null;
|
|
122
|
+
try {
|
|
123
|
+
existingMarker = fs.readFileSync(markerPath, 'utf8');
|
|
124
|
+
} catch (e) {
|
|
125
|
+
// No marker — fresh cache
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (existingMarker !== currentMarker) {
|
|
129
|
+
// New build process — clear old extensions
|
|
130
|
+
try {
|
|
131
|
+
const files = fs.readdirSync(cacheDir);
|
|
132
|
+
for (const file of files) {
|
|
133
|
+
if (file !== '.build-marker') {
|
|
134
|
+
fs.unlinkSync(nodePath.join(cacheDir, file));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {
|
|
138
|
+
// Ignore cleanup errors
|
|
139
|
+
}
|
|
140
|
+
fs.writeFileSync(markerPath, currentMarker);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Write an expanded extension callback to the cache.
|
|
146
|
+
* Uses @babel/generator to convert AST to source, then writes atomically.
|
|
147
|
+
*
|
|
148
|
+
* @param {string} rootDir - Project root directory
|
|
149
|
+
* @param {string} componentName - Component name (e.g., 'Text')
|
|
150
|
+
* @param {object} expandedCallback - Expanded AST node (ArrowFunctionExpression)
|
|
151
|
+
* @param {'extension'|'override'} type - Type of style modification
|
|
152
|
+
*/
|
|
153
|
+
function writeExtensionToCache(rootDir, componentName, expandedCallback, type) {
|
|
154
|
+
const cacheDir = getCacheDir(rootDir);
|
|
155
|
+
initCache(rootDir);
|
|
156
|
+
|
|
157
|
+
// Generate source code from AST
|
|
158
|
+
let generate;
|
|
159
|
+
try {
|
|
160
|
+
generate = require('@babel/generator').default || require('@babel/generator');
|
|
161
|
+
} catch (e) {
|
|
162
|
+
// If generator not available, skip file caching (single-worker fallback)
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const source = generate(expandedCallback).code;
|
|
167
|
+
const hash = crypto.createHash('md5').update(source).digest('hex').substring(0, 12);
|
|
168
|
+
|
|
169
|
+
// Track this hash so we don't re-read our own extensions in this worker
|
|
170
|
+
_writtenHashes.add(`${componentName}-${type}-${hash}`);
|
|
171
|
+
|
|
172
|
+
const filename = `${componentName}-${type}-${hash}.js`;
|
|
173
|
+
const filepath = nodePath.join(cacheDir, filename);
|
|
174
|
+
|
|
175
|
+
// Atomic write: write to temp file, then rename
|
|
176
|
+
const tmpPath = filepath + '.tmp.' + process.pid;
|
|
177
|
+
try {
|
|
178
|
+
fs.writeFileSync(tmpPath, source, 'utf8');
|
|
179
|
+
fs.renameSync(tmpPath, filepath);
|
|
180
|
+
} catch (e) {
|
|
181
|
+
// Clean up temp file on error
|
|
182
|
+
try { fs.unlinkSync(tmpPath); } catch (_) {}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Read all cached extensions for a component.
|
|
188
|
+
* Returns parsed AST nodes ready for merging.
|
|
189
|
+
*
|
|
190
|
+
* @param {object} t - Babel types
|
|
191
|
+
* @param {string} rootDir - Project root directory
|
|
192
|
+
* @param {string} componentName - Component name
|
|
193
|
+
* @returns {{ extensions: object[], override: object|null }}
|
|
194
|
+
*/
|
|
195
|
+
function readExtensionsFromCache(t, rootDir, componentName) {
|
|
196
|
+
const cacheDir = getCacheDir(rootDir);
|
|
197
|
+
const result = { extensions: [], override: null };
|
|
198
|
+
|
|
199
|
+
let files;
|
|
200
|
+
try {
|
|
201
|
+
files = fs.readdirSync(cacheDir);
|
|
202
|
+
} catch (e) {
|
|
203
|
+
return result; // Cache dir doesn't exist yet
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let parse;
|
|
207
|
+
try {
|
|
208
|
+
parse = require('@babel/parser').parse;
|
|
209
|
+
} catch (e) {
|
|
210
|
+
return result; // Parser not available
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Find all extension/override files for this component
|
|
214
|
+
const prefix = `${componentName}-`;
|
|
215
|
+
const relevantFiles = files.filter(f => f.startsWith(prefix) && f.endsWith('.js'))
|
|
216
|
+
.sort(); // Sort for deterministic order
|
|
217
|
+
|
|
218
|
+
for (const file of relevantFiles) {
|
|
219
|
+
// Extract type and hash from filename: ComponentName-type-hash.js
|
|
220
|
+
const match = file.match(/^.+-(extension|override)-([a-f0-9]+)\.js$/);
|
|
221
|
+
if (!match) continue;
|
|
222
|
+
|
|
223
|
+
const type = match[1];
|
|
224
|
+
const hash = match[2];
|
|
225
|
+
const key = `${componentName}-${type}-${hash}`;
|
|
226
|
+
|
|
227
|
+
// Skip extensions we wrote in this worker — they're already in the in-memory registry
|
|
228
|
+
if (_writtenHashes.has(key)) continue;
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
const source = fs.readFileSync(nodePath.join(cacheDir, file), 'utf8');
|
|
232
|
+
|
|
233
|
+
// Parse source back into AST
|
|
234
|
+
const ast = parse(source, {
|
|
235
|
+
sourceType: 'module',
|
|
236
|
+
plugins: ['typescript', 'jsx'],
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// The parsed file contains a single expression statement (the arrow function)
|
|
240
|
+
// Extract it from the program body
|
|
241
|
+
if (ast.program.body.length > 0) {
|
|
242
|
+
const stmt = ast.program.body[0];
|
|
243
|
+
let expr = null;
|
|
244
|
+
if (t.isExpressionStatement(stmt)) {
|
|
245
|
+
expr = stmt.expression;
|
|
246
|
+
}
|
|
247
|
+
if (expr) {
|
|
248
|
+
if (type === 'override') {
|
|
249
|
+
result.override = expr;
|
|
250
|
+
} else {
|
|
251
|
+
result.extensions.push(expr);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} catch (e) {
|
|
256
|
+
// Skip unreadable/unparseable files
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Reset the file-based cache. Used for testing.
|
|
265
|
+
*/
|
|
266
|
+
function resetStyleCache() {
|
|
267
|
+
_cacheDir = null;
|
|
268
|
+
_cacheInitialized = false;
|
|
269
|
+
_writtenHashes.clear();
|
|
270
|
+
// Also clear in-memory registry
|
|
271
|
+
for (const key of Object.keys(styleRegistry)) {
|
|
272
|
+
delete styleRegistry[key];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
65
276
|
// ============================================================================
|
|
66
277
|
// AST Deep Merge - Merges style object ASTs at build time
|
|
67
278
|
// ============================================================================
|
|
@@ -116,9 +327,15 @@ function mergeObjectExpressions(t, target, source) {
|
|
|
116
327
|
|
|
117
328
|
if (existingProp) {
|
|
118
329
|
// Both have this property - need to merge or replace
|
|
119
|
-
|
|
330
|
+
let existingValue = existingProp.value;
|
|
120
331
|
const newValue = prop.value;
|
|
121
332
|
|
|
333
|
+
// Unwrap TSAsExpression (e.g., from "as const") to get at the inner value
|
|
334
|
+
const existingHasTSAs = t.isTSAsExpression(existingValue);
|
|
335
|
+
if (existingHasTSAs) {
|
|
336
|
+
existingValue = existingValue.expression;
|
|
337
|
+
}
|
|
338
|
+
|
|
122
339
|
// If both are objects, deep merge
|
|
123
340
|
if (t.isObjectExpression(existingValue) && t.isObjectExpression(newValue)) {
|
|
124
341
|
const mergedValue = mergeObjectExpressions(t, existingValue, newValue);
|
|
@@ -805,7 +1022,7 @@ function buildMemberExpression(t, base, chain) {
|
|
|
805
1022
|
// Babel Plugin
|
|
806
1023
|
// ============================================================================
|
|
807
1024
|
|
|
808
|
-
|
|
1025
|
+
function idealystStylesPlugin({ types: t }) {
|
|
809
1026
|
// Store babel types for use in extractThemeKeysFromAST
|
|
810
1027
|
babelTypes = t;
|
|
811
1028
|
|
|
@@ -945,16 +1162,24 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
945
1162
|
if (t.isIdentifier(node.callee, { name: 'extendStyle' })) {
|
|
946
1163
|
debug(`FOUND extendStyle in: ${filename}`);
|
|
947
1164
|
|
|
948
|
-
const [componentNameArg,
|
|
1165
|
+
const [componentNameArg, stylesArg] = node.arguments;
|
|
949
1166
|
|
|
950
1167
|
if (!t.isStringLiteral(componentNameArg)) {
|
|
951
1168
|
debug(` SKIP - componentName is not a string literal`);
|
|
952
1169
|
return;
|
|
953
1170
|
}
|
|
954
1171
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1172
|
+
// Accept either a function callback or a plain object
|
|
1173
|
+
let stylesCallback = stylesArg;
|
|
1174
|
+
if (t.isObjectExpression(stylesArg)) {
|
|
1175
|
+
// Wrap plain object in an arrow function: (theme) => ({ ... })
|
|
1176
|
+
stylesCallback = t.arrowFunctionExpression(
|
|
1177
|
+
[t.identifier('theme')],
|
|
1178
|
+
t.parenthesizedExpression(stylesArg)
|
|
1179
|
+
);
|
|
1180
|
+
} else if (!t.isArrowFunctionExpression(stylesArg) &&
|
|
1181
|
+
!t.isFunctionExpression(stylesArg)) {
|
|
1182
|
+
debug(` SKIP - second argument is not a function or object`);
|
|
958
1183
|
return;
|
|
959
1184
|
}
|
|
960
1185
|
|
|
@@ -973,11 +1198,14 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
973
1198
|
const expandedVariants = [];
|
|
974
1199
|
const expandedCallback = expandIterators(t, stylesCallback, themeParam, keys, verbose, expandedVariants);
|
|
975
1200
|
|
|
976
|
-
// Store in registry for
|
|
1201
|
+
// Store in in-memory registry (fast path for same-worker)
|
|
977
1202
|
const entry = getOrCreateEntry(componentName);
|
|
978
1203
|
entry.extensions.push(expandedCallback);
|
|
979
1204
|
entry.themeParam = themeParam;
|
|
980
1205
|
|
|
1206
|
+
// Write to file cache (cross-worker persistence)
|
|
1207
|
+
writeExtensionToCache(rootDir, componentName, expandedCallback, 'extension');
|
|
1208
|
+
|
|
981
1209
|
debug(` -> Stored extension for '${componentName}' (${entry.extensions.length} total)`);
|
|
982
1210
|
|
|
983
1211
|
// Remove the extendStyle call (it's been captured)
|
|
@@ -991,16 +1219,24 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
991
1219
|
if (t.isIdentifier(node.callee, { name: 'overrideStyle' })) {
|
|
992
1220
|
debug(`FOUND overrideStyle in: ${filename}`);
|
|
993
1221
|
|
|
994
|
-
const [componentNameArg,
|
|
1222
|
+
const [componentNameArg, stylesArg] = node.arguments;
|
|
995
1223
|
|
|
996
1224
|
if (!t.isStringLiteral(componentNameArg)) {
|
|
997
1225
|
debug(` SKIP - componentName is not a string literal`);
|
|
998
1226
|
return;
|
|
999
1227
|
}
|
|
1000
1228
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1229
|
+
// Accept either a function callback or a plain object
|
|
1230
|
+
let stylesCallback = stylesArg;
|
|
1231
|
+
if (t.isObjectExpression(stylesArg)) {
|
|
1232
|
+
// Wrap plain object in an arrow function: (theme) => ({ ... })
|
|
1233
|
+
stylesCallback = t.arrowFunctionExpression(
|
|
1234
|
+
[t.identifier('theme')],
|
|
1235
|
+
t.parenthesizedExpression(stylesArg)
|
|
1236
|
+
);
|
|
1237
|
+
} else if (!t.isArrowFunctionExpression(stylesArg) &&
|
|
1238
|
+
!t.isFunctionExpression(stylesArg)) {
|
|
1239
|
+
debug(` SKIP - second argument is not a function or object`);
|
|
1004
1240
|
return;
|
|
1005
1241
|
}
|
|
1006
1242
|
|
|
@@ -1017,11 +1253,14 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
1017
1253
|
const expandedVariants = [];
|
|
1018
1254
|
const expandedCallback = expandIterators(t, stylesCallback, themeParam, keys, verbose, expandedVariants);
|
|
1019
1255
|
|
|
1020
|
-
// Store as override (
|
|
1256
|
+
// Store as override in in-memory registry (fast path for same-worker)
|
|
1021
1257
|
const entry = getOrCreateEntry(componentName);
|
|
1022
1258
|
entry.override = expandedCallback;
|
|
1023
1259
|
entry.themeParam = themeParam;
|
|
1024
1260
|
|
|
1261
|
+
// Write to file cache (cross-worker persistence)
|
|
1262
|
+
writeExtensionToCache(rootDir, componentName, expandedCallback, 'override');
|
|
1263
|
+
|
|
1025
1264
|
debug(` -> Stored override for '${componentName}'`);
|
|
1026
1265
|
|
|
1027
1266
|
// Remove the overrideStyle call
|
|
@@ -1078,16 +1317,23 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
1078
1317
|
let expandedCallback = expandIterators(t, stylesCallback, themeParam, keys, verbose, expandedVariants);
|
|
1079
1318
|
|
|
1080
1319
|
// Check for registered override or extensions
|
|
1320
|
+
// Combine in-memory registry (same worker) with file cache (cross-worker)
|
|
1081
1321
|
const entry = getOrCreateEntry(componentName);
|
|
1322
|
+
const cached = readExtensionsFromCache(t, rootDir, componentName);
|
|
1323
|
+
|
|
1324
|
+
// Determine override: in-memory takes precedence, then file cache
|
|
1325
|
+
const override = entry.override || cached.override;
|
|
1326
|
+
// Combine extensions: in-memory first, then file cache (already deduplicated)
|
|
1327
|
+
const allExtensions = [...entry.extensions, ...cached.extensions];
|
|
1082
1328
|
|
|
1083
|
-
if (
|
|
1329
|
+
if (override) {
|
|
1084
1330
|
// Override completely replaces base
|
|
1085
1331
|
debug(` -> Using override for '${componentName}'`);
|
|
1086
|
-
expandedCallback =
|
|
1087
|
-
} else if (
|
|
1332
|
+
expandedCallback = override;
|
|
1333
|
+
} else if (allExtensions.length > 0) {
|
|
1088
1334
|
// Merge extensions into base
|
|
1089
|
-
debug(` -> Merging ${
|
|
1090
|
-
for (const ext of
|
|
1335
|
+
debug(` -> Merging ${allExtensions.length} extensions for '${componentName}' (${entry.extensions.length} in-memory, ${cached.extensions.length} from cache)`);
|
|
1336
|
+
for (const ext of allExtensions) {
|
|
1091
1337
|
expandedCallback = mergeCallbackBodies(t, expandedCallback, ext);
|
|
1092
1338
|
}
|
|
1093
1339
|
}
|
|
@@ -1161,4 +1407,8 @@ module.exports = function idealystStylesPlugin({ types: t }) {
|
|
|
1161
1407
|
},
|
|
1162
1408
|
},
|
|
1163
1409
|
};
|
|
1164
|
-
}
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// Export plugin as default (Babel convention) with test utilities
|
|
1413
|
+
module.exports = idealystStylesPlugin;
|
|
1414
|
+
module.exports.resetStyleCache = resetStyleCache;
|
package/src/styleBuilder.ts
CHANGED
|
@@ -102,18 +102,27 @@ export function defineStyle<TTheme, TStyles extends Record<string, unknown>>(
|
|
|
102
102
|
/**
|
|
103
103
|
* Extend existing component styles (merged at build time).
|
|
104
104
|
* Import BEFORE components for extensions to apply.
|
|
105
|
+
*
|
|
106
|
+
* Accepts either a plain style object or a theme callback:
|
|
107
|
+
* ```typescript
|
|
108
|
+
* // Plain object (no theme access needed)
|
|
109
|
+
* extendStyle('Text', { text: { fontFamily: 'MyFont' } });
|
|
110
|
+
*
|
|
111
|
+
* // Theme callback (when you need theme tokens)
|
|
112
|
+
* extendStyle('Text', (theme) => ({ text: { color: theme.colors.text.primary } }));
|
|
113
|
+
* ```
|
|
105
114
|
*/
|
|
106
115
|
export function extendStyle<K extends keyof ComponentStyleRegistry>(
|
|
107
116
|
componentName: K,
|
|
108
|
-
styles: (theme: any) => ExtendStyleDef<K>
|
|
117
|
+
styles: ExtendStyleDef<K> | ((theme: any) => ExtendStyleDef<K>)
|
|
109
118
|
): void;
|
|
110
119
|
export function extendStyle<K extends string>(
|
|
111
120
|
componentName: K,
|
|
112
|
-
styles: (theme: any) => Record<string, any>
|
|
121
|
+
styles: Record<string, any> | ((theme: any) => Record<string, any>)
|
|
113
122
|
): void;
|
|
114
123
|
export function extendStyle(
|
|
115
124
|
_componentName: string,
|
|
116
|
-
_styles:
|
|
125
|
+
_styles: any
|
|
117
126
|
): void {
|
|
118
127
|
// Babel removes this call and merges into defineStyle
|
|
119
128
|
}
|
|
@@ -121,18 +130,27 @@ export function extendStyle(
|
|
|
121
130
|
/**
|
|
122
131
|
* Override component styles completely (replaces base at build time).
|
|
123
132
|
* Import BEFORE components for overrides to apply.
|
|
133
|
+
*
|
|
134
|
+
* Accepts either a plain style object or a theme callback:
|
|
135
|
+
* ```typescript
|
|
136
|
+
* // Plain object
|
|
137
|
+
* overrideStyle('Text', { text: { fontFamily: 'MyFont' } });
|
|
138
|
+
*
|
|
139
|
+
* // Theme callback
|
|
140
|
+
* overrideStyle('Text', (theme) => ({ text: { color: theme.colors.text.primary } }));
|
|
141
|
+
* ```
|
|
124
142
|
*/
|
|
125
143
|
export function overrideStyle<K extends keyof ComponentStyleRegistry>(
|
|
126
144
|
componentName: K,
|
|
127
|
-
styles: (theme: any) => OverrideStyleDef<K>
|
|
145
|
+
styles: OverrideStyleDef<K> | ((theme: any) => OverrideStyleDef<K>)
|
|
128
146
|
): void;
|
|
129
147
|
export function overrideStyle<K extends string>(
|
|
130
148
|
componentName: K,
|
|
131
|
-
styles: (theme: any) => Record<string, any>
|
|
149
|
+
styles: Record<string, any> | ((theme: any) => Record<string, any>)
|
|
132
150
|
): void;
|
|
133
151
|
export function overrideStyle(
|
|
134
152
|
_componentName: string,
|
|
135
|
-
_styles:
|
|
153
|
+
_styles: any
|
|
136
154
|
): void {
|
|
137
155
|
// Babel removes this call and replaces defineStyle
|
|
138
156
|
}
|