@kbach/react 0.6.1 → 0.6.2

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/index.d.mts CHANGED
@@ -1,9 +1,137 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
3
- import { T as ThemeColors, a as ThemeConfig, P as ParsedClass, R as ResolvedStyle, S as StyleValue, F as FrameworkConfig, b as ResolvedConfig, c as ThemeMode } from './types-BESBQANS.mjs';
4
- export { d as PluginAPI } from './types-BESBQANS.mjs';
5
3
  export { r as registerWebElement } from './web-substitute-CfpYFnE7.mjs';
6
4
 
5
+ /**
6
+ * Unified modifier registry — single source of truth for ALL modifier behavior.
7
+ *
8
+ * Adding a new modifier requires editing ONLY this file:
9
+ * 1. Add an entry to BUILTIN_MODIFIERS with its CSS and JS behavior.
10
+ * 2. Done — parser, resolver, CSS generator, and JSX runtime all derive
11
+ * their behavior from this data automatically.
12
+ *
13
+ * Plugin authors can register custom modifiers via registerModifier().
14
+ */
15
+ interface ModifierDef {
16
+ /** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
17
+ pseudo?: string;
18
+ /** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
19
+ ancestorSelector?: string;
20
+ /** Directionality attribute selector prefix INCLUDING trailing space (e.g. '[dir="rtl"] ') */
21
+ dirSelector?: string;
22
+ /** @media query body WITHOUT the '@media ' prefix (e.g. 'print', '(orientation: landscape)') */
23
+ mediaQuery?: string;
24
+ /** Dark/light mode scheme — triggers the configured darkMode strategy in CSS output */
25
+ darkScheme?: 'dark' | 'light';
26
+ /** True for responsive modifiers — wraps in @media (min-width: theme.screens[name]) */
27
+ isResponsive?: boolean;
28
+ /**
29
+ * Forces !important on all declarations in the generated CSS rule.
30
+ * Applied automatically for structural / ancestor / media modifiers that must
31
+ * win over base inline styles.
32
+ */
33
+ forcesImportant?: boolean;
34
+ /**
35
+ * How the JSX runtime routes this modifier:
36
+ * 'interactive' — managed by InteractiveWrapper (hover, focus, pressed, …)
37
+ * 'mode' — managed by DarkWrapper (dark, light, not-dark, …)
38
+ * 'responsive' — managed by DarkWrapper (sm, md, lg, xl, 2xl)
39
+ * 'css-only' — CSS injection only; matchModifier always returns false
40
+ */
41
+ jsBehavior: 'interactive' | 'mode' | 'responsive' | 'css-only';
42
+ /**
43
+ * Evaluates whether this modifier's condition is met at runtime.
44
+ * Omit for 'css-only' modifiers — they never apply as inline styles.
45
+ */
46
+ jsMatch?: (isDark: boolean, state: Record<string, boolean | undefined>, breakpoints: Set<string>) => boolean;
47
+ }
48
+
49
+ type ThemeMode = 'light' | 'dark' | 'system';
50
+ interface StyleValue {
51
+ [key: string]: string | number | undefined | null | StyleValue | StyleValue[];
52
+ }
53
+ interface ParsedClass {
54
+ /** The original class string, e.g. "dark:hover:bg-[#fff]" */
55
+ original: string;
56
+ /** Up to 3 modifier prefixes, e.g. ['dark', 'hover'] */
57
+ modifiers: string[];
58
+ /** Whether a leading `-` was present for negative values */
59
+ negative: boolean;
60
+ /** Whether a leading `!` was present — applies !important to all CSS declarations */
61
+ important: boolean;
62
+ /** The utility name, e.g. 'bg', 'p', 'text' */
63
+ utility: string;
64
+ /** The resolved value, e.g. 'white', '#fff', '4' */
65
+ value: string;
66
+ /** Whether the value was specified with bracket notation [value] */
67
+ isArbitrary: boolean;
68
+ }
69
+ interface ResolvedStyle {
70
+ /** Base styles applied unconditionally */
71
+ base?: StyleValue;
72
+ /** Styles keyed by modifier or modifier combo, e.g. 'dark', 'hover', 'dark:hover' */
73
+ [modifierKey: string]: StyleValue | undefined;
74
+ }
75
+ type ColorShades = Record<string, string>;
76
+ type ThemeColors = Record<string, string | ColorShades>;
77
+ type ThemeSpacing = Record<string, number | string>;
78
+ interface ThemeConfig {
79
+ colors: ThemeColors;
80
+ spacing: ThemeSpacing;
81
+ fontSize: Record<string, number | string>;
82
+ fontFamily: Record<string, string | string[]>;
83
+ fontWeight: Record<string, string | number>;
84
+ borderRadius: Record<string, number | string>;
85
+ borderWidth: Record<string, number>;
86
+ opacity: Record<string, number>;
87
+ lineHeight: Record<string, number | string>;
88
+ letterSpacing: Record<string, number | string>;
89
+ zIndex: Record<string, number | string>;
90
+ flex: Record<string, number | string>;
91
+ shadow: Record<string, StyleValue>;
92
+ screens: Record<string, string | number>;
93
+ [key: string]: unknown;
94
+ }
95
+ /**
96
+ * 'class' — toggles .dark class on <html>
97
+ * 'media' — uses prefers-color-scheme media query
98
+ * 'attribute' — uses data-theme="dark" attribute on <html>
99
+ */
100
+ type DarkMode = 'attribute' | 'class' | 'media';
101
+ interface PluginAPI {
102
+ addUtility(name: string, styles: StyleValue): void;
103
+ /**
104
+ * Register a custom variant.
105
+ *
106
+ * Pass a CSS selector string for simple cases — it is automatically
107
+ * converted into a ModifierDef that generates correct CSS rules:
108
+ * addVariant('hocus', ':hover, :focus') // pseudo
109
+ * addVariant('supports-grid', '@media (display: grid)') // media
110
+ * addVariant('dark-green', '.dark-green') // ancestor selector
111
+ *
112
+ * Pass a full ModifierDef object for advanced control (e.g. JS-trackable
113
+ * interactive variants with custom jsMatch logic).
114
+ */
115
+ addVariant(name: string, selectorOrDef: string | ModifierDef): void;
116
+ theme(path: string, defaultValue?: unknown): unknown;
117
+ e(className: string): string;
118
+ }
119
+ interface FrameworkConfig {
120
+ darkMode?: DarkMode;
121
+ theme?: Partial<ThemeConfig>;
122
+ /** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
123
+ extend?: {
124
+ theme?: Partial<ThemeConfig>;
125
+ } & Partial<ThemeConfig>;
126
+ plugins?: Array<(api: PluginAPI) => void>;
127
+ content?: string[];
128
+ }
129
+ interface ResolvedConfig {
130
+ darkMode: DarkMode;
131
+ theme: ThemeConfig;
132
+ plugins: Array<(api: PluginAPI) => void>;
133
+ }
134
+
7
135
  declare const defaultColors: ThemeColors;
8
136
  declare const defaultTheme: ThemeConfig;
9
137
 
@@ -289,4 +417,4 @@ declare function kb(classString: string, isDark?: boolean): StyleValue | string;
289
417
  */
290
418
  declare function cx(...classes: Array<string | false | null | undefined>): string;
291
419
 
292
- export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, clearCache, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, setResolveTarget, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
420
+ export { type ColorScale, type ColorsAPI, type FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, type ParsedClass, type PluginAPI, type ResolvedConfig, type ResolvedStyle, type StyleValue, type StyledProps, type ThemeConfig, ThemeContext, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, clearCache, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, setResolveTarget, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,137 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
3
- import { T as ThemeColors, a as ThemeConfig, P as ParsedClass, R as ResolvedStyle, S as StyleValue, F as FrameworkConfig, b as ResolvedConfig, c as ThemeMode } from './types-BESBQANS.js';
4
- export { d as PluginAPI } from './types-BESBQANS.js';
5
3
  export { r as registerWebElement } from './web-substitute-CfpYFnE7.js';
6
4
 
5
+ /**
6
+ * Unified modifier registry — single source of truth for ALL modifier behavior.
7
+ *
8
+ * Adding a new modifier requires editing ONLY this file:
9
+ * 1. Add an entry to BUILTIN_MODIFIERS with its CSS and JS behavior.
10
+ * 2. Done — parser, resolver, CSS generator, and JSX runtime all derive
11
+ * their behavior from this data automatically.
12
+ *
13
+ * Plugin authors can register custom modifiers via registerModifier().
14
+ */
15
+ interface ModifierDef {
16
+ /** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
17
+ pseudo?: string;
18
+ /** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
19
+ ancestorSelector?: string;
20
+ /** Directionality attribute selector prefix INCLUDING trailing space (e.g. '[dir="rtl"] ') */
21
+ dirSelector?: string;
22
+ /** @media query body WITHOUT the '@media ' prefix (e.g. 'print', '(orientation: landscape)') */
23
+ mediaQuery?: string;
24
+ /** Dark/light mode scheme — triggers the configured darkMode strategy in CSS output */
25
+ darkScheme?: 'dark' | 'light';
26
+ /** True for responsive modifiers — wraps in @media (min-width: theme.screens[name]) */
27
+ isResponsive?: boolean;
28
+ /**
29
+ * Forces !important on all declarations in the generated CSS rule.
30
+ * Applied automatically for structural / ancestor / media modifiers that must
31
+ * win over base inline styles.
32
+ */
33
+ forcesImportant?: boolean;
34
+ /**
35
+ * How the JSX runtime routes this modifier:
36
+ * 'interactive' — managed by InteractiveWrapper (hover, focus, pressed, …)
37
+ * 'mode' — managed by DarkWrapper (dark, light, not-dark, …)
38
+ * 'responsive' — managed by DarkWrapper (sm, md, lg, xl, 2xl)
39
+ * 'css-only' — CSS injection only; matchModifier always returns false
40
+ */
41
+ jsBehavior: 'interactive' | 'mode' | 'responsive' | 'css-only';
42
+ /**
43
+ * Evaluates whether this modifier's condition is met at runtime.
44
+ * Omit for 'css-only' modifiers — they never apply as inline styles.
45
+ */
46
+ jsMatch?: (isDark: boolean, state: Record<string, boolean | undefined>, breakpoints: Set<string>) => boolean;
47
+ }
48
+
49
+ type ThemeMode = 'light' | 'dark' | 'system';
50
+ interface StyleValue {
51
+ [key: string]: string | number | undefined | null | StyleValue | StyleValue[];
52
+ }
53
+ interface ParsedClass {
54
+ /** The original class string, e.g. "dark:hover:bg-[#fff]" */
55
+ original: string;
56
+ /** Up to 3 modifier prefixes, e.g. ['dark', 'hover'] */
57
+ modifiers: string[];
58
+ /** Whether a leading `-` was present for negative values */
59
+ negative: boolean;
60
+ /** Whether a leading `!` was present — applies !important to all CSS declarations */
61
+ important: boolean;
62
+ /** The utility name, e.g. 'bg', 'p', 'text' */
63
+ utility: string;
64
+ /** The resolved value, e.g. 'white', '#fff', '4' */
65
+ value: string;
66
+ /** Whether the value was specified with bracket notation [value] */
67
+ isArbitrary: boolean;
68
+ }
69
+ interface ResolvedStyle {
70
+ /** Base styles applied unconditionally */
71
+ base?: StyleValue;
72
+ /** Styles keyed by modifier or modifier combo, e.g. 'dark', 'hover', 'dark:hover' */
73
+ [modifierKey: string]: StyleValue | undefined;
74
+ }
75
+ type ColorShades = Record<string, string>;
76
+ type ThemeColors = Record<string, string | ColorShades>;
77
+ type ThemeSpacing = Record<string, number | string>;
78
+ interface ThemeConfig {
79
+ colors: ThemeColors;
80
+ spacing: ThemeSpacing;
81
+ fontSize: Record<string, number | string>;
82
+ fontFamily: Record<string, string | string[]>;
83
+ fontWeight: Record<string, string | number>;
84
+ borderRadius: Record<string, number | string>;
85
+ borderWidth: Record<string, number>;
86
+ opacity: Record<string, number>;
87
+ lineHeight: Record<string, number | string>;
88
+ letterSpacing: Record<string, number | string>;
89
+ zIndex: Record<string, number | string>;
90
+ flex: Record<string, number | string>;
91
+ shadow: Record<string, StyleValue>;
92
+ screens: Record<string, string | number>;
93
+ [key: string]: unknown;
94
+ }
95
+ /**
96
+ * 'class' — toggles .dark class on <html>
97
+ * 'media' — uses prefers-color-scheme media query
98
+ * 'attribute' — uses data-theme="dark" attribute on <html>
99
+ */
100
+ type DarkMode = 'attribute' | 'class' | 'media';
101
+ interface PluginAPI {
102
+ addUtility(name: string, styles: StyleValue): void;
103
+ /**
104
+ * Register a custom variant.
105
+ *
106
+ * Pass a CSS selector string for simple cases — it is automatically
107
+ * converted into a ModifierDef that generates correct CSS rules:
108
+ * addVariant('hocus', ':hover, :focus') // pseudo
109
+ * addVariant('supports-grid', '@media (display: grid)') // media
110
+ * addVariant('dark-green', '.dark-green') // ancestor selector
111
+ *
112
+ * Pass a full ModifierDef object for advanced control (e.g. JS-trackable
113
+ * interactive variants with custom jsMatch logic).
114
+ */
115
+ addVariant(name: string, selectorOrDef: string | ModifierDef): void;
116
+ theme(path: string, defaultValue?: unknown): unknown;
117
+ e(className: string): string;
118
+ }
119
+ interface FrameworkConfig {
120
+ darkMode?: DarkMode;
121
+ theme?: Partial<ThemeConfig>;
122
+ /** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
123
+ extend?: {
124
+ theme?: Partial<ThemeConfig>;
125
+ } & Partial<ThemeConfig>;
126
+ plugins?: Array<(api: PluginAPI) => void>;
127
+ content?: string[];
128
+ }
129
+ interface ResolvedConfig {
130
+ darkMode: DarkMode;
131
+ theme: ThemeConfig;
132
+ plugins: Array<(api: PluginAPI) => void>;
133
+ }
134
+
7
135
  declare const defaultColors: ThemeColors;
8
136
  declare const defaultTheme: ThemeConfig;
9
137
 
@@ -289,4 +417,4 @@ declare function kb(classString: string, isDark?: boolean): StyleValue | string;
289
417
  */
290
418
  declare function cx(...classes: Array<string | false | null | undefined>): string;
291
419
 
292
- export { type ColorScale, type ColorsAPI, FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, ParsedClass, ResolvedConfig, ResolvedStyle, StyleValue, type StyledProps, ThemeConfig, ThemeContext, type ThemeContextValue, ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, clearCache, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, setResolveTarget, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
420
+ export { type ColorScale, type ColorsAPI, type FrameworkConfig, type InteractionState, InteractiveWrapper, type InteractiveWrapperProps, type ParsedClass, type PluginAPI, type ResolvedConfig, type ResolvedStyle, type StyleValue, type StyledProps, type ThemeConfig, ThemeContext, type ThemeContextValue, type ThemeMode, ThemeProvider, type ThemeProviderProps, buildConfig, clearCache, cx, defaultColors, defaultTheme, disableRuntimeCSS, flatten, getConfig, initConfig, kb, normalizeClassString, parseClass, parseClasses, resolve, setResolveTarget, splitClassTokens, styled, updateConfig, useBreakpoint, useColors, useGlobalDarkMode, useIsDark, useResolvedStyle, useResponsive, useStyles, useTheme, wrapColors };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  "use strict";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
package/dist/index.mjs CHANGED
@@ -1,21 +1,9 @@
1
+ 'use client';
1
2
  import {
2
3
  EMPTY_BREAKPOINTS,
3
4
  InteractiveWrapper,
4
- chain,
5
- getWebTag,
6
- hasInteractiveBuckets,
7
- hasResponsiveBuckets,
8
- registerWebElement,
9
- setGlobalDarkMode,
10
- syncGlobalDarkMode,
11
- transformToWebProps,
12
- useConditionalWidth,
13
- useGlobalDarkMode,
14
- useGlobalWidth,
15
- useSyncExternalStore
16
- } from "./chunk-36QRQNPL.mjs";
17
- import {
18
5
  buildConfig,
6
+ chain,
19
7
  clearCache,
20
8
  defaultColors,
21
9
  defaultTheme,
@@ -23,6 +11,9 @@ import {
23
11
  flatten,
24
12
  getActiveBreakpoints,
25
13
  getConfig,
14
+ getWebTag,
15
+ hasInteractiveBuckets,
16
+ hasResponsiveBuckets,
26
17
  initConfig,
27
18
  isWeb,
28
19
  normalizeClassString,
@@ -30,14 +21,22 @@ import {
30
21
  parseClass,
31
22
  parseClasses,
32
23
  parseHexRgb,
24
+ registerWebElement,
33
25
  resolve,
26
+ setGlobalDarkMode,
34
27
  setGlobalWidth,
35
28
  setResolveTarget,
36
29
  splitClassTokens,
30
+ syncGlobalDarkMode,
37
31
  syncGlobalScreens,
38
32
  syncGlobalWidth,
39
- updateConfig
40
- } from "./chunk-MPHPB357.mjs";
33
+ transformToWebProps,
34
+ updateConfig,
35
+ useConditionalWidth,
36
+ useGlobalDarkMode,
37
+ useGlobalWidth,
38
+ useSyncExternalStore
39
+ } from "./chunk-GRZ6MVIL.mjs";
41
40
 
42
41
  // src/context.tsx
43
42
  import { createContext, useContext } from "react";
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  "use strict";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -1,10 +1,10 @@
1
+ 'use client';
1
2
  import {
2
3
  Fragment,
3
4
  jsx,
4
5
  jsxs
5
- } from "./chunk-6ZORO3BP.mjs";
6
- import "./chunk-36QRQNPL.mjs";
7
- import "./chunk-MPHPB357.mjs";
6
+ } from "./chunk-NWW57Q5Q.mjs";
7
+ import "./chunk-GRZ6MVIL.mjs";
8
8
 
9
9
  // src/jsx-dev-runtime.tsx
10
10
  function jsxDEV(type, props, key, isStaticChildren, source, self) {
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  "use strict";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -1,13 +1,13 @@
1
+ 'use client';
1
2
  import {
2
3
  Fragment,
3
4
  _invalidateDefaultFontCache,
4
5
  jsx,
5
6
  jsxs
6
- } from "./chunk-6ZORO3BP.mjs";
7
+ } from "./chunk-NWW57Q5Q.mjs";
7
8
  import {
8
9
  registerWebElement
9
- } from "./chunk-36QRQNPL.mjs";
10
- import "./chunk-MPHPB357.mjs";
10
+ } from "./chunk-GRZ6MVIL.mjs";
11
11
  export {
12
12
  Fragment,
13
13
  _invalidateDefaultFontCache,
@@ -1,5 +1,106 @@
1
1
  import { Plugin } from 'vite';
2
- import { F as FrameworkConfig } from './types-BESBQANS.mjs';
2
+
3
+ /**
4
+ * Unified modifier registry — single source of truth for ALL modifier behavior.
5
+ *
6
+ * Adding a new modifier requires editing ONLY this file:
7
+ * 1. Add an entry to BUILTIN_MODIFIERS with its CSS and JS behavior.
8
+ * 2. Done — parser, resolver, CSS generator, and JSX runtime all derive
9
+ * their behavior from this data automatically.
10
+ *
11
+ * Plugin authors can register custom modifiers via registerModifier().
12
+ */
13
+ interface ModifierDef {
14
+ /** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
15
+ pseudo?: string;
16
+ /** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
17
+ ancestorSelector?: string;
18
+ /** Directionality attribute selector prefix INCLUDING trailing space (e.g. '[dir="rtl"] ') */
19
+ dirSelector?: string;
20
+ /** @media query body WITHOUT the '@media ' prefix (e.g. 'print', '(orientation: landscape)') */
21
+ mediaQuery?: string;
22
+ /** Dark/light mode scheme — triggers the configured darkMode strategy in CSS output */
23
+ darkScheme?: 'dark' | 'light';
24
+ /** True for responsive modifiers — wraps in @media (min-width: theme.screens[name]) */
25
+ isResponsive?: boolean;
26
+ /**
27
+ * Forces !important on all declarations in the generated CSS rule.
28
+ * Applied automatically for structural / ancestor / media modifiers that must
29
+ * win over base inline styles.
30
+ */
31
+ forcesImportant?: boolean;
32
+ /**
33
+ * How the JSX runtime routes this modifier:
34
+ * 'interactive' — managed by InteractiveWrapper (hover, focus, pressed, …)
35
+ * 'mode' — managed by DarkWrapper (dark, light, not-dark, …)
36
+ * 'responsive' — managed by DarkWrapper (sm, md, lg, xl, 2xl)
37
+ * 'css-only' — CSS injection only; matchModifier always returns false
38
+ */
39
+ jsBehavior: 'interactive' | 'mode' | 'responsive' | 'css-only';
40
+ /**
41
+ * Evaluates whether this modifier's condition is met at runtime.
42
+ * Omit for 'css-only' modifiers — they never apply as inline styles.
43
+ */
44
+ jsMatch?: (isDark: boolean, state: Record<string, boolean | undefined>, breakpoints: Set<string>) => boolean;
45
+ }
46
+
47
+ interface StyleValue {
48
+ [key: string]: string | number | undefined | null | StyleValue | StyleValue[];
49
+ }
50
+ type ColorShades = Record<string, string>;
51
+ type ThemeColors = Record<string, string | ColorShades>;
52
+ type ThemeSpacing = Record<string, number | string>;
53
+ interface ThemeConfig {
54
+ colors: ThemeColors;
55
+ spacing: ThemeSpacing;
56
+ fontSize: Record<string, number | string>;
57
+ fontFamily: Record<string, string | string[]>;
58
+ fontWeight: Record<string, string | number>;
59
+ borderRadius: Record<string, number | string>;
60
+ borderWidth: Record<string, number>;
61
+ opacity: Record<string, number>;
62
+ lineHeight: Record<string, number | string>;
63
+ letterSpacing: Record<string, number | string>;
64
+ zIndex: Record<string, number | string>;
65
+ flex: Record<string, number | string>;
66
+ shadow: Record<string, StyleValue>;
67
+ screens: Record<string, string | number>;
68
+ [key: string]: unknown;
69
+ }
70
+ /**
71
+ * 'class' — toggles .dark class on <html>
72
+ * 'media' — uses prefers-color-scheme media query
73
+ * 'attribute' — uses data-theme="dark" attribute on <html>
74
+ */
75
+ type DarkMode = 'attribute' | 'class' | 'media';
76
+ interface PluginAPI {
77
+ addUtility(name: string, styles: StyleValue): void;
78
+ /**
79
+ * Register a custom variant.
80
+ *
81
+ * Pass a CSS selector string for simple cases — it is automatically
82
+ * converted into a ModifierDef that generates correct CSS rules:
83
+ * addVariant('hocus', ':hover, :focus') // pseudo
84
+ * addVariant('supports-grid', '@media (display: grid)') // media
85
+ * addVariant('dark-green', '.dark-green') // ancestor selector
86
+ *
87
+ * Pass a full ModifierDef object for advanced control (e.g. JS-trackable
88
+ * interactive variants with custom jsMatch logic).
89
+ */
90
+ addVariant(name: string, selectorOrDef: string | ModifierDef): void;
91
+ theme(path: string, defaultValue?: unknown): unknown;
92
+ e(className: string): string;
93
+ }
94
+ interface FrameworkConfig {
95
+ darkMode?: DarkMode;
96
+ theme?: Partial<ThemeConfig>;
97
+ /** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
98
+ extend?: {
99
+ theme?: Partial<ThemeConfig>;
100
+ } & Partial<ThemeConfig>;
101
+ plugins?: Array<(api: PluginAPI) => void>;
102
+ content?: string[];
103
+ }
3
104
 
4
105
  interface KbachPluginOptions {
5
106
  framework?: FrameworkConfig;
@@ -1,5 +1,106 @@
1
1
  import { Plugin } from 'vite';
2
- import { F as FrameworkConfig } from './types-BESBQANS.js';
2
+
3
+ /**
4
+ * Unified modifier registry — single source of truth for ALL modifier behavior.
5
+ *
6
+ * Adding a new modifier requires editing ONLY this file:
7
+ * 1. Add an entry to BUILTIN_MODIFIERS with its CSS and JS behavior.
8
+ * 2. Done — parser, resolver, CSS generator, and JSX runtime all derive
9
+ * their behavior from this data automatically.
10
+ *
11
+ * Plugin authors can register custom modifiers via registerModifier().
12
+ */
13
+ interface ModifierDef {
14
+ /** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
15
+ pseudo?: string;
16
+ /** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
17
+ ancestorSelector?: string;
18
+ /** Directionality attribute selector prefix INCLUDING trailing space (e.g. '[dir="rtl"] ') */
19
+ dirSelector?: string;
20
+ /** @media query body WITHOUT the '@media ' prefix (e.g. 'print', '(orientation: landscape)') */
21
+ mediaQuery?: string;
22
+ /** Dark/light mode scheme — triggers the configured darkMode strategy in CSS output */
23
+ darkScheme?: 'dark' | 'light';
24
+ /** True for responsive modifiers — wraps in @media (min-width: theme.screens[name]) */
25
+ isResponsive?: boolean;
26
+ /**
27
+ * Forces !important on all declarations in the generated CSS rule.
28
+ * Applied automatically for structural / ancestor / media modifiers that must
29
+ * win over base inline styles.
30
+ */
31
+ forcesImportant?: boolean;
32
+ /**
33
+ * How the JSX runtime routes this modifier:
34
+ * 'interactive' — managed by InteractiveWrapper (hover, focus, pressed, …)
35
+ * 'mode' — managed by DarkWrapper (dark, light, not-dark, …)
36
+ * 'responsive' — managed by DarkWrapper (sm, md, lg, xl, 2xl)
37
+ * 'css-only' — CSS injection only; matchModifier always returns false
38
+ */
39
+ jsBehavior: 'interactive' | 'mode' | 'responsive' | 'css-only';
40
+ /**
41
+ * Evaluates whether this modifier's condition is met at runtime.
42
+ * Omit for 'css-only' modifiers — they never apply as inline styles.
43
+ */
44
+ jsMatch?: (isDark: boolean, state: Record<string, boolean | undefined>, breakpoints: Set<string>) => boolean;
45
+ }
46
+
47
+ interface StyleValue {
48
+ [key: string]: string | number | undefined | null | StyleValue | StyleValue[];
49
+ }
50
+ type ColorShades = Record<string, string>;
51
+ type ThemeColors = Record<string, string | ColorShades>;
52
+ type ThemeSpacing = Record<string, number | string>;
53
+ interface ThemeConfig {
54
+ colors: ThemeColors;
55
+ spacing: ThemeSpacing;
56
+ fontSize: Record<string, number | string>;
57
+ fontFamily: Record<string, string | string[]>;
58
+ fontWeight: Record<string, string | number>;
59
+ borderRadius: Record<string, number | string>;
60
+ borderWidth: Record<string, number>;
61
+ opacity: Record<string, number>;
62
+ lineHeight: Record<string, number | string>;
63
+ letterSpacing: Record<string, number | string>;
64
+ zIndex: Record<string, number | string>;
65
+ flex: Record<string, number | string>;
66
+ shadow: Record<string, StyleValue>;
67
+ screens: Record<string, string | number>;
68
+ [key: string]: unknown;
69
+ }
70
+ /**
71
+ * 'class' — toggles .dark class on <html>
72
+ * 'media' — uses prefers-color-scheme media query
73
+ * 'attribute' — uses data-theme="dark" attribute on <html>
74
+ */
75
+ type DarkMode = 'attribute' | 'class' | 'media';
76
+ interface PluginAPI {
77
+ addUtility(name: string, styles: StyleValue): void;
78
+ /**
79
+ * Register a custom variant.
80
+ *
81
+ * Pass a CSS selector string for simple cases — it is automatically
82
+ * converted into a ModifierDef that generates correct CSS rules:
83
+ * addVariant('hocus', ':hover, :focus') // pseudo
84
+ * addVariant('supports-grid', '@media (display: grid)') // media
85
+ * addVariant('dark-green', '.dark-green') // ancestor selector
86
+ *
87
+ * Pass a full ModifierDef object for advanced control (e.g. JS-trackable
88
+ * interactive variants with custom jsMatch logic).
89
+ */
90
+ addVariant(name: string, selectorOrDef: string | ModifierDef): void;
91
+ theme(path: string, defaultValue?: unknown): unknown;
92
+ e(className: string): string;
93
+ }
94
+ interface FrameworkConfig {
95
+ darkMode?: DarkMode;
96
+ theme?: Partial<ThemeConfig>;
97
+ /** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
98
+ extend?: {
99
+ theme?: Partial<ThemeConfig>;
100
+ } & Partial<ThemeConfig>;
101
+ plugins?: Array<(api: PluginAPI) => void>;
102
+ content?: string[];
103
+ }
3
104
 
4
105
  interface KbachPluginOptions {
5
106
  framework?: FrameworkConfig;