@kbach/ui 0.1.0-beta.7 → 1.0.0-beta.1

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.
@@ -1,17 +0,0 @@
1
- 'use client';
2
- import {
3
- Fragment,
4
- _invalidateDefaultFontCache,
5
- jsx,
6
- jsxs
7
- } from "./chunk-UVXTWGHQ.mjs";
8
- import {
9
- registerWebElement
10
- } from "./chunk-LY753XBX.mjs";
11
- export {
12
- Fragment,
13
- _invalidateDefaultFontCache,
14
- jsx,
15
- jsxs,
16
- registerWebElement
17
- };
package/dist/native.js DELETED
@@ -1,78 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/native/index.ts
21
- var native_exports = {};
22
- __export(native_exports, {
23
- createKbachConfig: () => createKbachConfig,
24
- withKbach: () => withKbach,
25
- withKbachBabel: () => withKbachBabel
26
- });
27
- module.exports = __toCommonJS(native_exports);
28
-
29
- // src/native/setup.ts
30
- function warn(message) {
31
- const proc = process;
32
- const useColor = !!proc.stdout?.isTTY && !proc.env.NO_COLOR;
33
- const paint = (code, s) => useColor ? `\x1B[${code}m${s}\x1B[0m` : s;
34
- console.warn(`${paint("1", paint("35", "[kbach]"))} ${paint("33", message)}`);
35
- }
36
- function withKbach(metroConfig, _options = {}) {
37
- return metroConfig;
38
- }
39
- function withKbachBabel(babelConfig, options = {}) {
40
- const {
41
- configFile = "kbach.config.js",
42
- attributes = ["kb", "className"],
43
- debug = false
44
- } = options;
45
- const presets = (babelConfig.presets ?? []).map((preset) => {
46
- const [name, presetOpts = {}] = Array.isArray(preset) ? preset : [preset, {}];
47
- if (typeof name === "string" && (name.includes("babel-preset-expo") || name.includes("preset-react"))) {
48
- const opts = presetOpts;
49
- if (opts.jsxRuntime === "classic") {
50
- warn(`Forcing jsxRuntime "automatic" on ${name} (was "classic") \u2014 required for Kbach`);
51
- }
52
- return [name, { ...opts, jsxRuntime: "automatic" }];
53
- }
54
- return preset;
55
- });
56
- return {
57
- ...babelConfig,
58
- presets: [...presets, ["@kbach/ui/babel", { configFile, attributes, debug }]]
59
- };
60
- }
61
- function createKbachConfig(options = {}) {
62
- return {
63
- presets: [
64
- "babel-preset-expo",
65
- ["@kbach/ui/babel", {
66
- configFile: options.configFile ?? "kbach.config.js",
67
- attributes: options.attributes ?? ["kb", "className"],
68
- debug: options.debug ?? false
69
- }]
70
- ]
71
- };
72
- }
73
- // Annotate the CommonJS export names for ESM import in node:
74
- 0 && (module.exports = {
75
- createKbachConfig,
76
- withKbach,
77
- withKbachBabel
78
- });
package/dist/native.mjs DELETED
@@ -1,49 +0,0 @@
1
- // src/native/setup.ts
2
- function warn(message) {
3
- const proc = process;
4
- const useColor = !!proc.stdout?.isTTY && !proc.env.NO_COLOR;
5
- const paint = (code, s) => useColor ? `\x1B[${code}m${s}\x1B[0m` : s;
6
- console.warn(`${paint("1", paint("35", "[kbach]"))} ${paint("33", message)}`);
7
- }
8
- function withKbach(metroConfig, _options = {}) {
9
- return metroConfig;
10
- }
11
- function withKbachBabel(babelConfig, options = {}) {
12
- const {
13
- configFile = "kbach.config.js",
14
- attributes = ["kb", "className"],
15
- debug = false
16
- } = options;
17
- const presets = (babelConfig.presets ?? []).map((preset) => {
18
- const [name, presetOpts = {}] = Array.isArray(preset) ? preset : [preset, {}];
19
- if (typeof name === "string" && (name.includes("babel-preset-expo") || name.includes("preset-react"))) {
20
- const opts = presetOpts;
21
- if (opts.jsxRuntime === "classic") {
22
- warn(`Forcing jsxRuntime "automatic" on ${name} (was "classic") \u2014 required for Kbach`);
23
- }
24
- return [name, { ...opts, jsxRuntime: "automatic" }];
25
- }
26
- return preset;
27
- });
28
- return {
29
- ...babelConfig,
30
- presets: [...presets, ["@kbach/ui/babel", { configFile, attributes, debug }]]
31
- };
32
- }
33
- function createKbachConfig(options = {}) {
34
- return {
35
- presets: [
36
- "babel-preset-expo",
37
- ["@kbach/ui/babel", {
38
- configFile: options.configFile ?? "kbach.config.js",
39
- attributes: options.attributes ?? ["kb", "className"],
40
- debug: options.debug ?? false
41
- }]
42
- ]
43
- };
44
- }
45
- export {
46
- createKbachConfig,
47
- withKbach,
48
- withKbachBabel
49
- };
@@ -1,174 +0,0 @@
1
- import { Plugin } from 'vite';
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
- /**
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;
30
- /** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
31
- pseudo?: string;
32
- /** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
33
- ancestorSelector?: string;
34
- /** Directionality attribute selector prefix INCLUDING trailing space (e.g. '[dir="rtl"] ') */
35
- dirSelector?: string;
36
- /** @media query body WITHOUT the '@media ' prefix (e.g. 'print', '(orientation: landscape)') */
37
- mediaQuery?: string;
38
- /** Dark/light mode scheme — triggers the configured darkMode strategy in CSS output */
39
- darkScheme?: 'dark' | 'light';
40
- /** True for responsive modifiers — wraps in @media (min-width: theme.screens[name]) */
41
- isResponsive?: boolean;
42
- /**
43
- * Forces !important on all declarations in the generated CSS rule.
44
- * Applied automatically for structural / ancestor / media modifiers that must
45
- * win over base inline styles.
46
- */
47
- forcesImportant?: boolean;
48
- /**
49
- * How the JSX runtime routes this modifier:
50
- * 'interactive' — managed by InteractiveWrapper (hover, focus, pressed, …)
51
- * 'mode' — managed by DarkWrapper (dark, light, not-dark, …)
52
- * 'responsive' — managed by DarkWrapper (sm, md, lg, xl, 2xl)
53
- * 'css-only' — CSS injection only; matchModifier always returns false
54
- */
55
- jsBehavior: 'interactive' | 'mode' | 'responsive' | 'css-only';
56
- /**
57
- * Evaluates whether this modifier's condition is met at runtime.
58
- * Omit for 'css-only' modifiers — they never apply as inline styles.
59
- */
60
- jsMatch?: (isDark: boolean, state: Record<string, boolean | undefined>, breakpoints: Set<string>) => boolean;
61
- }
62
-
63
- interface StyleValue {
64
- [key: string]: string | number | undefined | null | StyleValue | StyleValue[];
65
- }
66
- /**
67
- * A color value is either a plain string (hex/rgb/alias-to-another-color-name)
68
- * or a mode-aware pair — resolved to `light` or `dark` per the active theme
69
- * mode wherever it's actually used (className resolution, useColors()).
70
- */
71
- type ColorValue = string | {
72
- light: string;
73
- dark: string;
74
- };
75
- type ColorShades = Record<string, ColorValue>;
76
- type ThemeColors = Record<string, ColorValue | 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
- /**
94
- * Custom @keyframes, web only. Each key is a keyframe name, its value maps
95
- * percentage/from/to selectors to a plain CSS declaration object (camelCase
96
- * properties, same shape as an inline style object):
97
- * keyframes: { wiggle: { '0%, 100%': { transform: 'rotate(-3deg)' }, '50%': { transform: 'rotate(3deg)' } } }
98
- * Referenced from `animation` below, or directly via animate-[wiggle_1s_ease-in-out].
99
- */
100
- keyframes: Record<string, Record<string, StyleValue>>;
101
- /**
102
- * Named animation shorthands built on `keyframes` above, referenced via
103
- * animate-{name} (e.g. animate-wiggle):
104
- * animation: { wiggle: 'wiggle 1s ease-in-out infinite' }
105
- * The first word must match a `keyframes` key so its @keyframes rule can be
106
- * injected alongside the animation — a name with no matching keyframes entry
107
- * still sets the `animation` CSS property, it just won't animate anything.
108
- */
109
- animation: Record<string, string>;
110
- [key: string]: unknown;
111
- }
112
- /**
113
- * 'class' — toggles .dark class on <html>
114
- * 'media' — uses prefers-color-scheme media query
115
- * 'attribute' — uses data-theme="dark" attribute on <html>
116
- */
117
- type DarkMode = 'attribute' | 'class' | 'media';
118
- interface PluginAPI {
119
- addUtility(name: string, styles: StyleValue): void;
120
- /**
121
- * Register a custom variant.
122
- *
123
- * Pass a CSS selector string for simple cases — it is automatically
124
- * converted into a ModifierDef that generates correct CSS rules:
125
- * addVariant('hocus', ':hover, :focus') // pseudo
126
- * addVariant('supports-grid', '@media (display: grid)') // media
127
- * addVariant('dark-green', '.dark-green') // ancestor selector
128
- *
129
- * Pass a full ModifierDef object for advanced control (e.g. JS-trackable
130
- * interactive variants with custom jsMatch logic).
131
- */
132
- addVariant(name: string, selectorOrDef: string | ModifierDef): void;
133
- theme(path: string, defaultValue?: unknown): unknown;
134
- e(className: string): string;
135
- }
136
- interface FrameworkConfig {
137
- darkMode?: DarkMode;
138
- theme?: Partial<ThemeConfig>;
139
- /** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
140
- extend?: {
141
- theme?: Partial<ThemeConfig>;
142
- } & Partial<ThemeConfig>;
143
- plugins?: Array<(api: PluginAPI) => void>;
144
- content?: string[];
145
- }
146
-
147
- declare function formatKbachCSS(tokenCSS: Map<string, string>, theme: ThemeConfig, responsiveRe: RegExp): string;
148
- declare function extractClassStrings(code: string): string[];
149
- interface KbachPluginOptions {
150
- framework?: FrameworkConfig;
151
- /** Directories to scan for class strings (relative to Vite root). Defaults to common source dirs. */
152
- include?: string[];
153
- /**
154
- * Class names to always include in the generated kbach.css, even if no
155
- * scan finds them literally in your source. Static extraction only ever
156
- * sees complete class strings as they appear in your files — it can't
157
- * evaluate `` `bg-${color}-${shade}` `` or similar runtime-built strings,
158
- * because the actual value doesn't exist until the component renders (see
159
- * useStyles()'s own docblock for the same limitation from the other
160
- * direction). Same purpose as Tailwind's `safelist` config: list the
161
- * complete class names explicitly, e.g. generated from the same
162
- * color/shade arrays your component already loops over —
163
- *
164
- * ```js
165
- * const families = ['red', 'blue', 'green'];
166
- * const shades = [1, 2, 3];
167
- * safelist: families.flatMap((f) => shades.map((s) => `bg-${f}-${s}`))
168
- * ```
169
- */
170
- safelist?: string[];
171
- }
172
- declare function kbach(userConfigOrOptions?: FrameworkConfig | KbachPluginOptions): Plugin;
173
-
174
- export { type KbachPluginOptions, extractClassStrings, formatKbachCSS, kbach };
@@ -1,174 +0,0 @@
1
- import { Plugin } from 'vite';
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
- /**
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;
30
- /** CSS pseudo-class or pseudo-element appended to the selector (e.g. ':hover', '::before') */
31
- pseudo?: string;
32
- /** Ancestor selector prefix INCLUDING trailing space (e.g. '.group:hover ', '.peer:focus ~ ') */
33
- ancestorSelector?: string;
34
- /** Directionality attribute selector prefix INCLUDING trailing space (e.g. '[dir="rtl"] ') */
35
- dirSelector?: string;
36
- /** @media query body WITHOUT the '@media ' prefix (e.g. 'print', '(orientation: landscape)') */
37
- mediaQuery?: string;
38
- /** Dark/light mode scheme — triggers the configured darkMode strategy in CSS output */
39
- darkScheme?: 'dark' | 'light';
40
- /** True for responsive modifiers — wraps in @media (min-width: theme.screens[name]) */
41
- isResponsive?: boolean;
42
- /**
43
- * Forces !important on all declarations in the generated CSS rule.
44
- * Applied automatically for structural / ancestor / media modifiers that must
45
- * win over base inline styles.
46
- */
47
- forcesImportant?: boolean;
48
- /**
49
- * How the JSX runtime routes this modifier:
50
- * 'interactive' — managed by InteractiveWrapper (hover, focus, pressed, …)
51
- * 'mode' — managed by DarkWrapper (dark, light, not-dark, …)
52
- * 'responsive' — managed by DarkWrapper (sm, md, lg, xl, 2xl)
53
- * 'css-only' — CSS injection only; matchModifier always returns false
54
- */
55
- jsBehavior: 'interactive' | 'mode' | 'responsive' | 'css-only';
56
- /**
57
- * Evaluates whether this modifier's condition is met at runtime.
58
- * Omit for 'css-only' modifiers — they never apply as inline styles.
59
- */
60
- jsMatch?: (isDark: boolean, state: Record<string, boolean | undefined>, breakpoints: Set<string>) => boolean;
61
- }
62
-
63
- interface StyleValue {
64
- [key: string]: string | number | undefined | null | StyleValue | StyleValue[];
65
- }
66
- /**
67
- * A color value is either a plain string (hex/rgb/alias-to-another-color-name)
68
- * or a mode-aware pair — resolved to `light` or `dark` per the active theme
69
- * mode wherever it's actually used (className resolution, useColors()).
70
- */
71
- type ColorValue = string | {
72
- light: string;
73
- dark: string;
74
- };
75
- type ColorShades = Record<string, ColorValue>;
76
- type ThemeColors = Record<string, ColorValue | 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
- /**
94
- * Custom @keyframes, web only. Each key is a keyframe name, its value maps
95
- * percentage/from/to selectors to a plain CSS declaration object (camelCase
96
- * properties, same shape as an inline style object):
97
- * keyframes: { wiggle: { '0%, 100%': { transform: 'rotate(-3deg)' }, '50%': { transform: 'rotate(3deg)' } } }
98
- * Referenced from `animation` below, or directly via animate-[wiggle_1s_ease-in-out].
99
- */
100
- keyframes: Record<string, Record<string, StyleValue>>;
101
- /**
102
- * Named animation shorthands built on `keyframes` above, referenced via
103
- * animate-{name} (e.g. animate-wiggle):
104
- * animation: { wiggle: 'wiggle 1s ease-in-out infinite' }
105
- * The first word must match a `keyframes` key so its @keyframes rule can be
106
- * injected alongside the animation — a name with no matching keyframes entry
107
- * still sets the `animation` CSS property, it just won't animate anything.
108
- */
109
- animation: Record<string, string>;
110
- [key: string]: unknown;
111
- }
112
- /**
113
- * 'class' — toggles .dark class on <html>
114
- * 'media' — uses prefers-color-scheme media query
115
- * 'attribute' — uses data-theme="dark" attribute on <html>
116
- */
117
- type DarkMode = 'attribute' | 'class' | 'media';
118
- interface PluginAPI {
119
- addUtility(name: string, styles: StyleValue): void;
120
- /**
121
- * Register a custom variant.
122
- *
123
- * Pass a CSS selector string for simple cases — it is automatically
124
- * converted into a ModifierDef that generates correct CSS rules:
125
- * addVariant('hocus', ':hover, :focus') // pseudo
126
- * addVariant('supports-grid', '@media (display: grid)') // media
127
- * addVariant('dark-green', '.dark-green') // ancestor selector
128
- *
129
- * Pass a full ModifierDef object for advanced control (e.g. JS-trackable
130
- * interactive variants with custom jsMatch logic).
131
- */
132
- addVariant(name: string, selectorOrDef: string | ModifierDef): void;
133
- theme(path: string, defaultValue?: unknown): unknown;
134
- e(className: string): string;
135
- }
136
- interface FrameworkConfig {
137
- darkMode?: DarkMode;
138
- theme?: Partial<ThemeConfig>;
139
- /** Additive theme extension — accepts either `extend.theme.X` or `extend.X` directly. */
140
- extend?: {
141
- theme?: Partial<ThemeConfig>;
142
- } & Partial<ThemeConfig>;
143
- plugins?: Array<(api: PluginAPI) => void>;
144
- content?: string[];
145
- }
146
-
147
- declare function formatKbachCSS(tokenCSS: Map<string, string>, theme: ThemeConfig, responsiveRe: RegExp): string;
148
- declare function extractClassStrings(code: string): string[];
149
- interface KbachPluginOptions {
150
- framework?: FrameworkConfig;
151
- /** Directories to scan for class strings (relative to Vite root). Defaults to common source dirs. */
152
- include?: string[];
153
- /**
154
- * Class names to always include in the generated kbach.css, even if no
155
- * scan finds them literally in your source. Static extraction only ever
156
- * sees complete class strings as they appear in your files — it can't
157
- * evaluate `` `bg-${color}-${shade}` `` or similar runtime-built strings,
158
- * because the actual value doesn't exist until the component renders (see
159
- * useStyles()'s own docblock for the same limitation from the other
160
- * direction). Same purpose as Tailwind's `safelist` config: list the
161
- * complete class names explicitly, e.g. generated from the same
162
- * color/shade arrays your component already loops over —
163
- *
164
- * ```js
165
- * const families = ['red', 'blue', 'green'];
166
- * const shades = [1, 2, 3];
167
- * safelist: families.flatMap((f) => shades.map((s) => `bg-${f}-${s}`))
168
- * ```
169
- */
170
- safelist?: string[];
171
- }
172
- declare function kbach(userConfigOrOptions?: FrameworkConfig | KbachPluginOptions): Plugin;
173
-
174
- export { type KbachPluginOptions, extractClassStrings, formatKbachCSS, kbach };