windrunner 1.0.2 → 1.1.0
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/LICENSE +15 -15
- package/README.md +328 -240
- package/dist/index.d.ts +62 -33
- package/dist/index.esm.js +235 -5
- package/dist/index.js +238 -5
- package/dist/index.min.js +3 -3
- package/package.json +58 -58
package/dist/index.js
CHANGED
|
@@ -21,7 +21,10 @@ var index_exports = {};
|
|
|
21
21
|
__export(index_exports, {
|
|
22
22
|
compileClass: () => compileClass,
|
|
23
23
|
createWindrunner: () => createWindrunner,
|
|
24
|
+
defineResponsiveUtilities: () => defineResponsiveUtilities,
|
|
25
|
+
defineUtilities: () => defineUtilities,
|
|
24
26
|
parseClass: () => parseClass,
|
|
27
|
+
plugin: () => plugin,
|
|
25
28
|
windrunner: () => windrunner
|
|
26
29
|
});
|
|
27
30
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -3288,13 +3291,160 @@ function buildDivideDeclaration(baseToken, theme2) {
|
|
|
3288
3291
|
return void 0;
|
|
3289
3292
|
}
|
|
3290
3293
|
|
|
3294
|
+
// src/plugins.js
|
|
3295
|
+
var PluginRegistry = class {
|
|
3296
|
+
constructor() {
|
|
3297
|
+
this.utilities = /* @__PURE__ */ new Map();
|
|
3298
|
+
this.variants = /* @__PURE__ */ new Map();
|
|
3299
|
+
}
|
|
3300
|
+
/**
|
|
3301
|
+
* Register a custom utility
|
|
3302
|
+
* @param {string|RegExp} pattern - Class name pattern (e.g., "glass" or /^glass-(.+)$/)
|
|
3303
|
+
* @param {Function|string} handler - Function that returns CSS or CSS string
|
|
3304
|
+
*/
|
|
3305
|
+
addUtility(pattern, handler) {
|
|
3306
|
+
this.utilities.set(pattern, handler);
|
|
3307
|
+
}
|
|
3308
|
+
/**
|
|
3309
|
+
* Register multiple utilities at once
|
|
3310
|
+
* @param {Object} utilities - Object mapping patterns to handlers
|
|
3311
|
+
*/
|
|
3312
|
+
addUtilities(utilities) {
|
|
3313
|
+
Object.entries(utilities).forEach(([pattern, handler]) => {
|
|
3314
|
+
this.addUtility(pattern, handler);
|
|
3315
|
+
});
|
|
3316
|
+
}
|
|
3317
|
+
/**
|
|
3318
|
+
* Register a custom variant
|
|
3319
|
+
* @param {string} name - Variant name (e.g., "parent-hover")
|
|
3320
|
+
* @param {Function} handler - Function that transforms selector
|
|
3321
|
+
*/
|
|
3322
|
+
addVariant(name, handler) {
|
|
3323
|
+
this.variants.set(name, handler);
|
|
3324
|
+
}
|
|
3325
|
+
/**
|
|
3326
|
+
* Register multiple variants at once
|
|
3327
|
+
* @param {Object} variants - Object mapping names to handlers
|
|
3328
|
+
*/
|
|
3329
|
+
addVariants(variants2) {
|
|
3330
|
+
Object.entries(variants2).forEach(([name, handler]) => {
|
|
3331
|
+
this.addVariant(name, handler);
|
|
3332
|
+
});
|
|
3333
|
+
}
|
|
3334
|
+
/**
|
|
3335
|
+
* Check if a token matches any custom utility pattern
|
|
3336
|
+
* @param {string} token - The base token to match
|
|
3337
|
+
* @returns {Object|null} - { handler, match } or null
|
|
3338
|
+
*/
|
|
3339
|
+
matchUtility(token) {
|
|
3340
|
+
for (const [pattern, handler] of this.utilities) {
|
|
3341
|
+
if (pattern instanceof RegExp) {
|
|
3342
|
+
const match = pattern.exec(token);
|
|
3343
|
+
if (match) {
|
|
3344
|
+
return { handler, match };
|
|
3345
|
+
}
|
|
3346
|
+
} else if (pattern === token) {
|
|
3347
|
+
return { handler, match: [token] };
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
return null;
|
|
3351
|
+
}
|
|
3352
|
+
/**
|
|
3353
|
+
* Check if a variant name matches any custom variant
|
|
3354
|
+
* @param {string} variantName - The variant to check
|
|
3355
|
+
* @returns {Function|null} - Handler function or null
|
|
3356
|
+
*/
|
|
3357
|
+
matchVariant(variantName) {
|
|
3358
|
+
return this.variants.get(variantName) || null;
|
|
3359
|
+
}
|
|
3360
|
+
/**
|
|
3361
|
+
* Get all registered utility patterns (for debugging)
|
|
3362
|
+
*/
|
|
3363
|
+
getUtilities() {
|
|
3364
|
+
return Array.from(this.utilities.keys());
|
|
3365
|
+
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Get all registered variant names (for debugging)
|
|
3368
|
+
*/
|
|
3369
|
+
getVariants() {
|
|
3370
|
+
return Array.from(this.variants.keys());
|
|
3371
|
+
}
|
|
3372
|
+
/**
|
|
3373
|
+
* Clear all registered plugins
|
|
3374
|
+
*/
|
|
3375
|
+
clear() {
|
|
3376
|
+
this.utilities.clear();
|
|
3377
|
+
this.variants.clear();
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
function plugin(handler) {
|
|
3381
|
+
if (typeof handler !== "function") {
|
|
3382
|
+
throw new Error("Plugin handler must be a function");
|
|
3383
|
+
}
|
|
3384
|
+
return {
|
|
3385
|
+
__isWindrunnerPlugin: true,
|
|
3386
|
+
handler
|
|
3387
|
+
};
|
|
3388
|
+
}
|
|
3389
|
+
function isPlugin(obj) {
|
|
3390
|
+
return obj && obj.__isWindrunnerPlugin === true && typeof obj.handler === "function";
|
|
3391
|
+
}
|
|
3392
|
+
function defineUtilities(definitions) {
|
|
3393
|
+
const utilities = {};
|
|
3394
|
+
Object.entries(definitions).forEach(([className, css]) => {
|
|
3395
|
+
utilities[className] = typeof css === "string" ? css : objectToCss(css);
|
|
3396
|
+
});
|
|
3397
|
+
return utilities;
|
|
3398
|
+
}
|
|
3399
|
+
function defineResponsiveUtilities(base, values, toDeclaration) {
|
|
3400
|
+
const utilities = {};
|
|
3401
|
+
Object.entries(values).forEach(([key, value]) => {
|
|
3402
|
+
const className = key === "DEFAULT" ? base : `${base}-${key}`;
|
|
3403
|
+
utilities[className] = toDeclaration(key, value);
|
|
3404
|
+
});
|
|
3405
|
+
return utilities;
|
|
3406
|
+
}
|
|
3407
|
+
function objectToCss(obj) {
|
|
3408
|
+
return Object.entries(obj).map(([prop, value]) => `${prop}: ${value};`).join(" ");
|
|
3409
|
+
}
|
|
3410
|
+
|
|
3291
3411
|
// src/compiler.js
|
|
3292
|
-
function compileBaseToken(baseToken, theme2) {
|
|
3412
|
+
function compileBaseToken(baseToken, theme2, pluginRegistry) {
|
|
3413
|
+
if (pluginRegistry) {
|
|
3414
|
+
const pluginMatch = pluginRegistry.matchUtility(baseToken);
|
|
3415
|
+
if (pluginMatch) {
|
|
3416
|
+
const { handler, match } = pluginMatch;
|
|
3417
|
+
try {
|
|
3418
|
+
if (typeof handler === "function") {
|
|
3419
|
+
const result = handler(match, theme2);
|
|
3420
|
+
if (result) return result;
|
|
3421
|
+
} else if (typeof handler === "string") {
|
|
3422
|
+
return handler;
|
|
3423
|
+
}
|
|
3424
|
+
} catch (error) {
|
|
3425
|
+
console.warn(`[Windrunner] Plugin utility handler error for "${baseToken}":`, error);
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3293
3429
|
return buildLayoutDeclaration(baseToken, theme2) || buildPositionInsetDeclaration(baseToken, theme2) || buildSpacingDeclaration(baseToken, theme2) || buildSpaceBetweenDeclaration(baseToken, theme2) || buildGapDeclaration(baseToken, theme2) || buildDimensionDeclaration(baseToken, theme2) || buildFlexGridDeclaration(baseToken, theme2) || buildBorderDeclaration(baseToken, theme2) || buildBorderRadiusDeclaration(baseToken, theme2) || buildBorderSpacingDeclaration(baseToken, theme2) || buildDivideDeclaration(baseToken, theme2) || buildOpacityDeclaration(baseToken, theme2) || buildShadowDeclaration(baseToken, theme2) || buildInsetShadowDeclaration(baseToken, theme2) || buildInsetRingDeclaration(baseToken, theme2) || buildRingDeclaration(baseToken, theme2) || buildRingOffsetDeclaration(baseToken, theme2) || buildTextShadowDeclaration(baseToken, theme2) || buildTransitionDeclaration(baseToken) || buildTransformDeclaration(baseToken, theme2) || buildFilterDeclaration(baseToken, theme2) || buildBackgroundDeclaration(baseToken, theme2) || buildGradientDeclaration(baseToken, theme2) || buildColorDeclaration(baseToken, theme2) || buildTypographyDeclaration(baseToken, theme2) || buildBlendingDeclaration(baseToken) || buildInteractivityDeclaration(baseToken, theme2) || buildAnimationDeclaration(baseToken) || buildMaskDeclaration(baseToken) || buildContainerQueryDeclaration(baseToken) || buildScrollSnapDeclaration(baseToken) || buildAccessibilityDeclaration(baseToken) || buildZoomDeclaration(baseToken, theme2) || buildForcedColorDeclaration(baseToken);
|
|
3294
3430
|
}
|
|
3295
|
-
function applyVariants(selector, variants2) {
|
|
3431
|
+
function applyVariants(selector, variants2, pluginRegistry) {
|
|
3296
3432
|
let currentSelector = selector;
|
|
3297
3433
|
for (const variant of variants2) {
|
|
3434
|
+
if (pluginRegistry) {
|
|
3435
|
+
const customHandler = pluginRegistry.matchVariant(variant);
|
|
3436
|
+
if (customHandler) {
|
|
3437
|
+
try {
|
|
3438
|
+
const result = customHandler(currentSelector);
|
|
3439
|
+
if (result) {
|
|
3440
|
+
currentSelector = result;
|
|
3441
|
+
continue;
|
|
3442
|
+
}
|
|
3443
|
+
} catch (error) {
|
|
3444
|
+
console.warn(`[Windrunner] Plugin variant handler error for "${variant}":`, error);
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3298
3448
|
switch (variant) {
|
|
3299
3449
|
case "dark":
|
|
3300
3450
|
currentSelector = `.dark ${currentSelector}`;
|
|
@@ -3335,15 +3485,66 @@ function applyVariants(selector, variants2) {
|
|
|
3335
3485
|
case "invalid":
|
|
3336
3486
|
currentSelector = `${currentSelector}:invalid`;
|
|
3337
3487
|
break;
|
|
3488
|
+
case "target":
|
|
3489
|
+
currentSelector = `${currentSelector}:target`;
|
|
3490
|
+
break;
|
|
3491
|
+
case "enabled":
|
|
3492
|
+
currentSelector = `${currentSelector}:enabled`;
|
|
3493
|
+
break;
|
|
3494
|
+
case "default":
|
|
3495
|
+
currentSelector = `${currentSelector}:default`;
|
|
3496
|
+
break;
|
|
3497
|
+
case "optional":
|
|
3498
|
+
currentSelector = `${currentSelector}:optional`;
|
|
3499
|
+
break;
|
|
3500
|
+
case "user-valid":
|
|
3501
|
+
currentSelector = `${currentSelector}:user-valid`;
|
|
3502
|
+
break;
|
|
3503
|
+
case "user-invalid":
|
|
3504
|
+
currentSelector = `${currentSelector}:user-invalid`;
|
|
3505
|
+
break;
|
|
3506
|
+
case "in-range":
|
|
3507
|
+
currentSelector = `${currentSelector}:in-range`;
|
|
3508
|
+
break;
|
|
3509
|
+
case "out-of-range":
|
|
3510
|
+
currentSelector = `${currentSelector}:out-of-range`;
|
|
3511
|
+
break;
|
|
3512
|
+
case "placeholder-shown":
|
|
3513
|
+
currentSelector = `${currentSelector}:placeholder-shown`;
|
|
3514
|
+
break;
|
|
3515
|
+
case "autofill":
|
|
3516
|
+
currentSelector = `${currentSelector}:autofill`;
|
|
3517
|
+
break;
|
|
3518
|
+
case "details-content":
|
|
3519
|
+
currentSelector = `${currentSelector}:details-content`;
|
|
3520
|
+
break;
|
|
3338
3521
|
case "placeholder":
|
|
3339
3522
|
currentSelector = `${currentSelector}::placeholder`;
|
|
3340
3523
|
break;
|
|
3524
|
+
case "backdrop":
|
|
3525
|
+
currentSelector = `${currentSelector}::backdrop`;
|
|
3526
|
+
break;
|
|
3341
3527
|
case "before":
|
|
3342
3528
|
currentSelector = `${currentSelector}::before`;
|
|
3343
3529
|
break;
|
|
3344
3530
|
case "after":
|
|
3345
3531
|
currentSelector = `${currentSelector}::after`;
|
|
3346
3532
|
break;
|
|
3533
|
+
case "first-letter":
|
|
3534
|
+
currentSelector = `${currentSelector}::first-letter`;
|
|
3535
|
+
break;
|
|
3536
|
+
case "first-line":
|
|
3537
|
+
currentSelector = `${currentSelector}::first-line`;
|
|
3538
|
+
break;
|
|
3539
|
+
case "marker":
|
|
3540
|
+
currentSelector = `${currentSelector}::marker`;
|
|
3541
|
+
break;
|
|
3542
|
+
case "selection":
|
|
3543
|
+
currentSelector = `${currentSelector}::selection`;
|
|
3544
|
+
break;
|
|
3545
|
+
case "file":
|
|
3546
|
+
currentSelector = `${currentSelector}::file-selector-button`;
|
|
3547
|
+
break;
|
|
3347
3548
|
case "first":
|
|
3348
3549
|
currentSelector = `${currentSelector}:first-child`;
|
|
3349
3550
|
break;
|
|
@@ -3424,11 +3625,40 @@ function applyVariants(selector, variants2) {
|
|
|
3424
3625
|
}
|
|
3425
3626
|
function resolveRuntimeContext(options = {}) {
|
|
3426
3627
|
const config = getConfigOptions(options, []);
|
|
3628
|
+
const pluginRegistry = new PluginRegistry();
|
|
3629
|
+
if (options.plugins && Array.isArray(options.plugins)) {
|
|
3630
|
+
options.plugins.forEach((pluginDef) => {
|
|
3631
|
+
if (isPlugin(pluginDef)) {
|
|
3632
|
+
try {
|
|
3633
|
+
pluginDef.handler({
|
|
3634
|
+
addUtility: (pattern, handler) => pluginRegistry.addUtility(pattern, handler),
|
|
3635
|
+
addUtilities: (utilities) => pluginRegistry.addUtilities(utilities),
|
|
3636
|
+
addVariant: (name, handler) => pluginRegistry.addVariant(name, handler),
|
|
3637
|
+
addVariants: (variants2) => pluginRegistry.addVariants(variants2),
|
|
3638
|
+
theme: (key) => {
|
|
3639
|
+
if (!key) return config.theme || {};
|
|
3640
|
+
const keys = key.split(".");
|
|
3641
|
+
let value = config.theme || {};
|
|
3642
|
+
for (const k of keys) {
|
|
3643
|
+
value = value[k];
|
|
3644
|
+
if (value === void 0) break;
|
|
3645
|
+
}
|
|
3646
|
+
return value;
|
|
3647
|
+
},
|
|
3648
|
+
config: () => config
|
|
3649
|
+
});
|
|
3650
|
+
} catch (error) {
|
|
3651
|
+
console.error("[Windrunner] Plugin initialization error:", error);
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
});
|
|
3655
|
+
}
|
|
3427
3656
|
return {
|
|
3428
3657
|
config,
|
|
3429
3658
|
theme: config.theme || {},
|
|
3430
3659
|
screens: config.theme && config.theme.screens || config.screens || {},
|
|
3431
|
-
containers: config.theme && config.theme.containers || config.containers || {}
|
|
3660
|
+
containers: config.theme && config.theme.containers || config.containers || {},
|
|
3661
|
+
plugins: pluginRegistry
|
|
3432
3662
|
};
|
|
3433
3663
|
}
|
|
3434
3664
|
function getBaseTailwindOptions(options = {}) {
|
|
@@ -3472,10 +3702,10 @@ function parseClass(className, screens = {}, containers = {}) {
|
|
|
3472
3702
|
function compileRuntimeClassNameWithContext(className, context) {
|
|
3473
3703
|
const parsed = parseClass(className, context.screens, context.containers);
|
|
3474
3704
|
if (!parsed) return "";
|
|
3475
|
-
const declaration = compileBaseToken(parsed.baseToken, context.theme);
|
|
3705
|
+
const declaration = compileBaseToken(parsed.baseToken, context.theme, context.plugins);
|
|
3476
3706
|
if (!declaration) return "";
|
|
3477
3707
|
const selector = `.${escapeCssIdentifier(parsed.original)}`;
|
|
3478
|
-
const variantSelector = applyVariants(selector, parsed.variants);
|
|
3708
|
+
const variantSelector = applyVariants(selector, parsed.variants, context.plugins);
|
|
3479
3709
|
if (!variantSelector) return "";
|
|
3480
3710
|
const finalDeclaration = appendImportant(
|
|
3481
3711
|
isChildScoped(declaration) ? declaration.declaration : declaration,
|
|
@@ -3766,6 +3996,9 @@ function windrunner(options = {}) {
|
|
|
3766
3996
|
0 && (module.exports = {
|
|
3767
3997
|
compileClass,
|
|
3768
3998
|
createWindrunner,
|
|
3999
|
+
defineResponsiveUtilities,
|
|
4000
|
+
defineUtilities,
|
|
3769
4001
|
parseClass,
|
|
4002
|
+
plugin,
|
|
3770
4003
|
windrunner
|
|
3771
4004
|
});
|