@kbach/react 0.6.39 → 0.6.40
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/dist/{chunk-NE4LAJXK.mjs → chunk-LQH3CJ3G.mjs} +155 -98
- package/dist/{chunk-Z4ZOGRZG.mjs → chunk-ZFVHIT3V.mjs} +4 -7
- package/dist/core/index.d.ts +17 -9
- package/dist/core/index.js +138 -94
- package/dist/index.js +26 -9
- package/dist/index.mjs +18 -4
- package/dist/jsx-dev-runtime.js +14 -12
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.js +14 -12
- package/dist/jsx-runtime.mjs +2 -2
- package/dist/vite-plugin.d.mts +18 -1
- package/dist/vite-plugin.d.ts +18 -1
- package/dist/vite-plugin.js +121 -87
- package/dist/vite-plugin.mjs +120 -87
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
buildConfig,
|
|
8
8
|
chain,
|
|
9
9
|
clearCache,
|
|
10
|
+
composeNativeStyle,
|
|
10
11
|
defaultColors,
|
|
11
12
|
defaultTheme,
|
|
12
13
|
disableRuntimeCSS,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
getActiveBreakpoints,
|
|
16
17
|
getConfig,
|
|
17
18
|
getEffectiveIsWeb,
|
|
19
|
+
getGlobalScreens,
|
|
18
20
|
getImpliedRNStyle,
|
|
19
21
|
getWebTag,
|
|
20
22
|
hasInteractiveBuckets,
|
|
@@ -30,6 +32,7 @@ import {
|
|
|
30
32
|
parseClasses,
|
|
31
33
|
parseHexRgb,
|
|
32
34
|
registerWebElement,
|
|
35
|
+
resetConfig,
|
|
33
36
|
resolve,
|
|
34
37
|
setGlobalDarkMode,
|
|
35
38
|
setGlobalWidth,
|
|
@@ -45,7 +48,7 @@ import {
|
|
|
45
48
|
useGlobalDarkMode,
|
|
46
49
|
useGlobalWidth,
|
|
47
50
|
useSyncExternalStore
|
|
48
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-LQH3CJ3G.mjs";
|
|
49
52
|
|
|
50
53
|
// src/context.tsx
|
|
51
54
|
import { createContext, useContext } from "react";
|
|
@@ -152,6 +155,7 @@ var _mountedProviderCount = 0;
|
|
|
152
155
|
var _warnedMultipleProviders = false;
|
|
153
156
|
var _mountedConfigOverrideCount = 0;
|
|
154
157
|
var _warnedConfigOverride = false;
|
|
158
|
+
var _warnedMediaModeToggle = false;
|
|
155
159
|
function loadPersistedMode() {
|
|
156
160
|
try {
|
|
157
161
|
if (isWeb) return localStorage.getItem(STORAGE_KEY);
|
|
@@ -230,6 +234,9 @@ function ThemeProvider({
|
|
|
230
234
|
return () => {
|
|
231
235
|
_mountedProviderCount--;
|
|
232
236
|
if (configOverride) _mountedConfigOverrideCount--;
|
|
237
|
+
if (_prevConfigOverrideRef.current !== void 0 && _mountedProviderCount === 0) {
|
|
238
|
+
resetConfig();
|
|
239
|
+
}
|
|
233
240
|
};
|
|
234
241
|
}, []);
|
|
235
242
|
const [webWidth, setWebWidth] = useState(0);
|
|
@@ -296,9 +303,15 @@ function ThemeProvider({
|
|
|
296
303
|
return () => window.removeEventListener("storage", onStorage);
|
|
297
304
|
}, [disablePersistence]);
|
|
298
305
|
const setMode = useCallback((next) => {
|
|
306
|
+
if (process.env.NODE_ENV !== "production" && isWeb && resolvedConfig.darkMode === "media" && !_warnedMediaModeToggle) {
|
|
307
|
+
_warnedMediaModeToggle = true;
|
|
308
|
+
kbachWarn(
|
|
309
|
+
'setMode()/toggle() was called while darkMode is "media" \u2014 the resolved mode/isDark from useTheme()/useIsDark() will update, but the actual CSS stays driven by prefers-color-scheme and will not change to match. Use darkMode: "attribute" or "class" if the app needs manual toggling.'
|
|
310
|
+
);
|
|
311
|
+
}
|
|
299
312
|
_setMode(next);
|
|
300
313
|
if (!disablePersistence) persistMode(next);
|
|
301
|
-
}, [disablePersistence]);
|
|
314
|
+
}, [disablePersistence, resolvedConfig.darkMode]);
|
|
302
315
|
const toggle = useCallback(() => {
|
|
303
316
|
setMode(mode === "dark" || mode === "system" && systemScheme === "dark" ? "light" : "dark");
|
|
304
317
|
}, [mode, systemScheme, setMode]);
|
|
@@ -403,9 +416,10 @@ function styled(Component, baseClasses = "") {
|
|
|
403
416
|
const needsWidth = hasResponsiveBuckets(resolved);
|
|
404
417
|
const width = useConditionalWidth(needsWidth && !isWebPlatform);
|
|
405
418
|
const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
|
|
419
|
+
const screens = getGlobalScreens();
|
|
406
420
|
const computedStyle = useMemo4(
|
|
407
421
|
() => isWebPlatform ? {} : flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
|
|
408
|
-
[resolved, isDark, pressed, hovered, focused, disabled, checked, width]
|
|
422
|
+
[resolved, isDark, pressed, hovered, focused, disabled, checked, width, screens]
|
|
409
423
|
// eslint-disable-line react-hooks/exhaustive-deps
|
|
410
424
|
);
|
|
411
425
|
const webTag = isWebPlatform ? getWebTag(Component, rest) : null;
|
|
@@ -414,7 +428,7 @@ function styled(Component, baseClasses = "") {
|
|
|
414
428
|
const compensation = getImpliedRNStyle(webTag, resolved.base);
|
|
415
429
|
if (!compensation) return flatStyleProp;
|
|
416
430
|
return flatStyleProp ? { ...compensation, ...flatStyleProp } : compensation;
|
|
417
|
-
})() :
|
|
431
|
+
})() : composeNativeStyle(computedStyle, styleProp);
|
|
418
432
|
const effectiveComponent = webTag ?? Component;
|
|
419
433
|
const componentName2 = Component.displayName ?? Component.name ?? "";
|
|
420
434
|
const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, webTag, rest) : rest;
|
package/dist/jsx-dev-runtime.js
CHANGED
|
@@ -163,6 +163,10 @@ function stripWebOnlyProps(s) {
|
|
|
163
163
|
delete s.position;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
+
function composeNativeStyle(computed, userStyle) {
|
|
167
|
+
if (!userStyle) return computed;
|
|
168
|
+
return Array.isArray(userStyle) ? [computed, ...userStyle] : [computed, userStyle];
|
|
169
|
+
}
|
|
166
170
|
|
|
167
171
|
// src/InteractiveWrapper.tsx
|
|
168
172
|
var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
@@ -188,6 +192,7 @@ var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
|
188
192
|
const needsWidth = hasResponsiveBuckets(resolvedStyle);
|
|
189
193
|
const width = useConditionalWidth(needsWidth && !isWebPlatform);
|
|
190
194
|
const breakpoints = needsWidth ? (0, import_core4.getActiveBreakpoints)(width) : EMPTY_BREAKPOINTS;
|
|
195
|
+
const screens = (0, import_core4.getGlobalScreens)();
|
|
191
196
|
const [pressed, setPressed] = (0, import_react2.useState)(false);
|
|
192
197
|
const [hovered, setHovered] = (0, import_react2.useState)(false);
|
|
193
198
|
const [focused, setFocused] = (0, import_react2.useState)(false);
|
|
@@ -231,10 +236,10 @@ var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
|
231
236
|
if (isNonStringComponent) stripWebOnlyProps(s);
|
|
232
237
|
return s;
|
|
233
238
|
},
|
|
234
|
-
[resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked, isNonStringComponent]
|
|
239
|
+
[resolvedStyle, isDark, pressed, hovered, focused, width, screens, disabled, checked, isNonStringComponent]
|
|
235
240
|
);
|
|
236
241
|
const skipComputedInline = isWebPlatform;
|
|
237
|
-
const finalStyle = skipComputedInline ? styleProp ?? void 0 :
|
|
242
|
+
const finalStyle = skipComputedInline ? styleProp ?? void 0 : composeNativeStyle(computedStyle, styleProp);
|
|
238
243
|
const componentProps = {
|
|
239
244
|
ref,
|
|
240
245
|
...restForComponent,
|
|
@@ -291,7 +296,7 @@ var DarkWrapper = import_react3.default.forwardRef(
|
|
|
291
296
|
return s;
|
|
292
297
|
}, [resolvedStyle, isDark, width, screens, isNonStringComponent]);
|
|
293
298
|
const skipComputedInline = isWebPlatform;
|
|
294
|
-
const finalStyle = skipComputedInline ? styleProp ?? void 0 :
|
|
299
|
+
const finalStyle = skipComputedInline ? styleProp ?? void 0 : composeNativeStyle(computedStyle, styleProp);
|
|
295
300
|
const props = { ref, ...rest, style: finalStyle };
|
|
296
301
|
return Array.isArray(children) ? import_react3.default.createElement(Component, props, ...children) : import_react3.default.createElement(Component, props, children);
|
|
297
302
|
}
|
|
@@ -403,8 +408,9 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
|
|
|
403
408
|
"lineBreakStrategyIOS",
|
|
404
409
|
// TextInput
|
|
405
410
|
"multiline",
|
|
406
|
-
|
|
407
|
-
// handled
|
|
411
|
+
// NOTE: 'resizeMode' (Image's prop, not TextInput's) deliberately does NOT
|
|
412
|
+
// go here — it's handled below in the isImage branch (mapped to CSS
|
|
413
|
+
// object-fit). Blacklisting it here would make that branch unreachable.
|
|
408
414
|
"blurOnSubmit",
|
|
409
415
|
"clearButtonMode",
|
|
410
416
|
"clearTextOnFocus",
|
|
@@ -530,7 +536,7 @@ function transformToWebProps(originalName, tag, props) {
|
|
|
530
536
|
continue;
|
|
531
537
|
}
|
|
532
538
|
if (k === "keyboardType") {
|
|
533
|
-
if (!("type" in props) && !
|
|
539
|
+
if (!("type" in props) && !props.secureTextEntry) {
|
|
534
540
|
const mapped = _keyboardTypeMap[v];
|
|
535
541
|
if (mapped) out.type = mapped;
|
|
536
542
|
}
|
|
@@ -546,7 +552,7 @@ function transformToWebProps(originalName, tag, props) {
|
|
|
546
552
|
}
|
|
547
553
|
}
|
|
548
554
|
if (isScrollable && k === "horizontal") {
|
|
549
|
-
if (v) pendingStyle = { display: "flex", flexDirection: "row", overflowX: "auto" };
|
|
555
|
+
if (v) pendingStyle = { ...pendingStyle ?? {}, display: "flex", flexDirection: "row", overflowX: "auto" };
|
|
550
556
|
continue;
|
|
551
557
|
}
|
|
552
558
|
if (k === "pointerEvents") {
|
|
@@ -640,10 +646,6 @@ function omitConsumed(props) {
|
|
|
640
646
|
}
|
|
641
647
|
return out;
|
|
642
648
|
}
|
|
643
|
-
function mergeStyle(computed, userStyle) {
|
|
644
|
-
if (!userStyle) return computed;
|
|
645
|
-
return Array.isArray(userStyle) ? [computed, ...userStyle] : [computed, userStyle];
|
|
646
|
-
}
|
|
647
649
|
function withImpliedRNStyleIfNeeded(webTag, resolvedBase, userStyle) {
|
|
648
650
|
const compensation = getImpliedRNStyle(webTag, resolvedBase);
|
|
649
651
|
if (!compensation) return userStyle;
|
|
@@ -719,7 +721,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
|
|
|
719
721
|
const computedStyle = (0, import_core6.flatten)(resolved, false);
|
|
720
722
|
stripInternalMarkers(computedStyle);
|
|
721
723
|
if (typeof effectiveType !== "string") stripWebOnlyProps(computedStyle);
|
|
722
|
-
finalStyle =
|
|
724
|
+
finalStyle = composeNativeStyle(computedStyle, userStyle);
|
|
723
725
|
} else {
|
|
724
726
|
finalStyle = userStyle ?? void 0;
|
|
725
727
|
}
|
package/dist/jsx-dev-runtime.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
Fragment,
|
|
4
4
|
jsx,
|
|
5
5
|
jsxs
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-ZFVHIT3V.mjs";
|
|
7
|
+
import "./chunk-LQH3CJ3G.mjs";
|
|
8
8
|
|
|
9
9
|
// src/jsx-dev-runtime.tsx
|
|
10
10
|
function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -164,6 +164,10 @@ function stripWebOnlyProps(s) {
|
|
|
164
164
|
delete s.position;
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
+
function composeNativeStyle(computed, userStyle) {
|
|
168
|
+
if (!userStyle) return computed;
|
|
169
|
+
return Array.isArray(userStyle) ? [computed, ...userStyle] : [computed, userStyle];
|
|
170
|
+
}
|
|
167
171
|
|
|
168
172
|
// src/InteractiveWrapper.tsx
|
|
169
173
|
var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
@@ -189,6 +193,7 @@ var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
|
189
193
|
const needsWidth = hasResponsiveBuckets(resolvedStyle);
|
|
190
194
|
const width = useConditionalWidth(needsWidth && !isWebPlatform);
|
|
191
195
|
const breakpoints = needsWidth ? (0, import_core4.getActiveBreakpoints)(width) : EMPTY_BREAKPOINTS;
|
|
196
|
+
const screens = (0, import_core4.getGlobalScreens)();
|
|
192
197
|
const [pressed, setPressed] = (0, import_react2.useState)(false);
|
|
193
198
|
const [hovered, setHovered] = (0, import_react2.useState)(false);
|
|
194
199
|
const [focused, setFocused] = (0, import_react2.useState)(false);
|
|
@@ -232,10 +237,10 @@ var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
|
232
237
|
if (isNonStringComponent) stripWebOnlyProps(s);
|
|
233
238
|
return s;
|
|
234
239
|
},
|
|
235
|
-
[resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked, isNonStringComponent]
|
|
240
|
+
[resolvedStyle, isDark, pressed, hovered, focused, width, screens, disabled, checked, isNonStringComponent]
|
|
236
241
|
);
|
|
237
242
|
const skipComputedInline = isWebPlatform;
|
|
238
|
-
const finalStyle = skipComputedInline ? styleProp ?? void 0 :
|
|
243
|
+
const finalStyle = skipComputedInline ? styleProp ?? void 0 : composeNativeStyle(computedStyle, styleProp);
|
|
239
244
|
const componentProps = {
|
|
240
245
|
ref,
|
|
241
246
|
...restForComponent,
|
|
@@ -292,7 +297,7 @@ var DarkWrapper = import_react3.default.forwardRef(
|
|
|
292
297
|
return s;
|
|
293
298
|
}, [resolvedStyle, isDark, width, screens, isNonStringComponent]);
|
|
294
299
|
const skipComputedInline = isWebPlatform;
|
|
295
|
-
const finalStyle = skipComputedInline ? styleProp ?? void 0 :
|
|
300
|
+
const finalStyle = skipComputedInline ? styleProp ?? void 0 : composeNativeStyle(computedStyle, styleProp);
|
|
296
301
|
const props = { ref, ...rest, style: finalStyle };
|
|
297
302
|
return Array.isArray(children) ? import_react3.default.createElement(Component, props, ...children) : import_react3.default.createElement(Component, props, children);
|
|
298
303
|
}
|
|
@@ -409,8 +414,9 @@ var _rnOnlyProps = /* @__PURE__ */ new Set([
|
|
|
409
414
|
"lineBreakStrategyIOS",
|
|
410
415
|
// TextInput
|
|
411
416
|
"multiline",
|
|
412
|
-
|
|
413
|
-
// handled
|
|
417
|
+
// NOTE: 'resizeMode' (Image's prop, not TextInput's) deliberately does NOT
|
|
418
|
+
// go here — it's handled below in the isImage branch (mapped to CSS
|
|
419
|
+
// object-fit). Blacklisting it here would make that branch unreachable.
|
|
414
420
|
"blurOnSubmit",
|
|
415
421
|
"clearButtonMode",
|
|
416
422
|
"clearTextOnFocus",
|
|
@@ -536,7 +542,7 @@ function transformToWebProps(originalName, tag, props) {
|
|
|
536
542
|
continue;
|
|
537
543
|
}
|
|
538
544
|
if (k === "keyboardType") {
|
|
539
|
-
if (!("type" in props) && !
|
|
545
|
+
if (!("type" in props) && !props.secureTextEntry) {
|
|
540
546
|
const mapped = _keyboardTypeMap[v];
|
|
541
547
|
if (mapped) out.type = mapped;
|
|
542
548
|
}
|
|
@@ -552,7 +558,7 @@ function transformToWebProps(originalName, tag, props) {
|
|
|
552
558
|
}
|
|
553
559
|
}
|
|
554
560
|
if (isScrollable && k === "horizontal") {
|
|
555
|
-
if (v) pendingStyle = { display: "flex", flexDirection: "row", overflowX: "auto" };
|
|
561
|
+
if (v) pendingStyle = { ...pendingStyle ?? {}, display: "flex", flexDirection: "row", overflowX: "auto" };
|
|
556
562
|
continue;
|
|
557
563
|
}
|
|
558
564
|
if (k === "pointerEvents") {
|
|
@@ -646,10 +652,6 @@ function omitConsumed(props) {
|
|
|
646
652
|
}
|
|
647
653
|
return out;
|
|
648
654
|
}
|
|
649
|
-
function mergeStyle(computed, userStyle) {
|
|
650
|
-
if (!userStyle) return computed;
|
|
651
|
-
return Array.isArray(userStyle) ? [computed, ...userStyle] : [computed, userStyle];
|
|
652
|
-
}
|
|
653
655
|
function withImpliedRNStyleIfNeeded(webTag, resolvedBase, userStyle) {
|
|
654
656
|
const compensation = getImpliedRNStyle(webTag, resolvedBase);
|
|
655
657
|
if (!compensation) return userStyle;
|
|
@@ -725,7 +727,7 @@ function processElement(type, rawProps, key, isStaticChildren) {
|
|
|
725
727
|
const computedStyle = (0, import_core6.flatten)(resolved, false);
|
|
726
728
|
stripInternalMarkers(computedStyle);
|
|
727
729
|
if (typeof effectiveType !== "string") stripWebOnlyProps(computedStyle);
|
|
728
|
-
finalStyle =
|
|
730
|
+
finalStyle = composeNativeStyle(computedStyle, userStyle);
|
|
729
731
|
} else {
|
|
730
732
|
finalStyle = userStyle ?? void 0;
|
|
731
733
|
}
|
package/dist/jsx-runtime.mjs
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
_invalidateDefaultFontCache,
|
|
5
5
|
jsx,
|
|
6
6
|
jsxs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZFVHIT3V.mjs";
|
|
8
8
|
import {
|
|
9
9
|
registerWebElement
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LQH3CJ3G.mjs";
|
|
11
11
|
export {
|
|
12
12
|
Fragment,
|
|
13
13
|
_invalidateDefaultFontCache,
|
package/dist/vite-plugin.d.mts
CHANGED
|
@@ -11,6 +11,22 @@ import { Plugin } from 'vite';
|
|
|
11
11
|
* Plugin authors can register custom modifiers via registerModifier().
|
|
12
12
|
*/
|
|
13
13
|
interface ModifierDef {
|
|
14
|
+
/**
|
|
15
|
+
* Cascade priority for CSS rule ORDER — NOT specificity. Two rules that
|
|
16
|
+
* differ only by modifier (e.g. `.hover\:bg-blue-6:hover` and
|
|
17
|
+
* `.focus\:bg-red-6:focus`) have equal CSS specificity, so when both
|
|
18
|
+
* conditions are true at once (hovering AND focused), the winner is
|
|
19
|
+
* whichever rule appears LATER in the stylesheet — CSS's normal same-
|
|
20
|
+
* specificity tiebreak. Without a fixed priority, "later" would depend on
|
|
21
|
+
* encounter order (whichever class the app happens to render/scan first),
|
|
22
|
+
* making the winner effectively random and inconsistent across reloads/
|
|
23
|
+
* builds. `order` fixes that: rules are emitted/injected sorted by this
|
|
24
|
+
* value (ascending — higher wins ties), regardless of source order, so
|
|
25
|
+
* e.g. `disabled:` always beats `hover:` on the same element no matter
|
|
26
|
+
* which one was written first in the className or rendered first in the
|
|
27
|
+
* app. Omit for the default (0). See getModifierOrder() below.
|
|
28
|
+
*/
|
|
29
|
+
order?: number;
|
|
14
30
|
/** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
|
|
15
31
|
pseudo?: string;
|
|
16
32
|
/** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
|
|
@@ -128,6 +144,7 @@ interface FrameworkConfig {
|
|
|
128
144
|
content?: string[];
|
|
129
145
|
}
|
|
130
146
|
|
|
147
|
+
declare function formatKbachCSS(tokenCSS: Map<string, string>, theme: ThemeConfig, responsiveRe: RegExp): string;
|
|
131
148
|
interface KbachPluginOptions {
|
|
132
149
|
framework?: FrameworkConfig;
|
|
133
150
|
/** Directories to scan for class strings (relative to Vite root). Defaults to common source dirs. */
|
|
@@ -135,4 +152,4 @@ interface KbachPluginOptions {
|
|
|
135
152
|
}
|
|
136
153
|
declare function kbach(userConfigOrOptions?: FrameworkConfig | KbachPluginOptions): Plugin;
|
|
137
154
|
|
|
138
|
-
export { type KbachPluginOptions, kbach };
|
|
155
|
+
export { type KbachPluginOptions, formatKbachCSS, kbach };
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -11,6 +11,22 @@ import { Plugin } from 'vite';
|
|
|
11
11
|
* Plugin authors can register custom modifiers via registerModifier().
|
|
12
12
|
*/
|
|
13
13
|
interface ModifierDef {
|
|
14
|
+
/**
|
|
15
|
+
* Cascade priority for CSS rule ORDER — NOT specificity. Two rules that
|
|
16
|
+
* differ only by modifier (e.g. `.hover\:bg-blue-6:hover` and
|
|
17
|
+
* `.focus\:bg-red-6:focus`) have equal CSS specificity, so when both
|
|
18
|
+
* conditions are true at once (hovering AND focused), the winner is
|
|
19
|
+
* whichever rule appears LATER in the stylesheet — CSS's normal same-
|
|
20
|
+
* specificity tiebreak. Without a fixed priority, "later" would depend on
|
|
21
|
+
* encounter order (whichever class the app happens to render/scan first),
|
|
22
|
+
* making the winner effectively random and inconsistent across reloads/
|
|
23
|
+
* builds. `order` fixes that: rules are emitted/injected sorted by this
|
|
24
|
+
* value (ascending — higher wins ties), regardless of source order, so
|
|
25
|
+
* e.g. `disabled:` always beats `hover:` on the same element no matter
|
|
26
|
+
* which one was written first in the className or rendered first in the
|
|
27
|
+
* app. Omit for the default (0). See getModifierOrder() below.
|
|
28
|
+
*/
|
|
29
|
+
order?: number;
|
|
14
30
|
/** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
|
|
15
31
|
pseudo?: string;
|
|
16
32
|
/** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
|
|
@@ -128,6 +144,7 @@ interface FrameworkConfig {
|
|
|
128
144
|
content?: string[];
|
|
129
145
|
}
|
|
130
146
|
|
|
147
|
+
declare function formatKbachCSS(tokenCSS: Map<string, string>, theme: ThemeConfig, responsiveRe: RegExp): string;
|
|
131
148
|
interface KbachPluginOptions {
|
|
132
149
|
framework?: FrameworkConfig;
|
|
133
150
|
/** Directories to scan for class strings (relative to Vite root). Defaults to common source dirs. */
|
|
@@ -135,4 +152,4 @@ interface KbachPluginOptions {
|
|
|
135
152
|
}
|
|
136
153
|
declare function kbach(userConfigOrOptions?: FrameworkConfig | KbachPluginOptions): Plugin;
|
|
137
154
|
|
|
138
|
-
export { type KbachPluginOptions, kbach };
|
|
155
|
+
export { type KbachPluginOptions, formatKbachCSS, kbach };
|