@kbach/react 0.5.6 → 0.5.8

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/README.md CHANGED
@@ -329,7 +329,7 @@ Available families: slate, gray, zinc, neutral, stone, red, orange, amber, yello
329
329
  | Category | Examples |
330
330
  |---|---|
331
331
  | Background | `bg-white`, `bg-gray-10`, `bg-blue-6`, `bg-[#fff]` |
332
- | Text | `text-sm`, `text-2xl`, `text-gray-10`, `font-bold` |
332
+ | Text | `text-sm`, `text-2xl`, `text-gray-10`, `font-bold`, `font-sans` |
333
333
  | Text wrap | `text-balance`, `text-pretty`, `text-nowrap`, `text-wrap` |
334
334
  | Line clamp | `line-clamp-3`, `line-clamp-none` |
335
335
  | Padding | `p-4`, `px-6`, `py-3` |
@@ -389,3 +389,44 @@ import { updateConfig } from '@kbach/react';
389
389
 
390
390
  updateConfig({ extend: { theme: { colors: { brand: { 6: '#6366f1' } } } } });
391
391
  ```
392
+
393
+ ### Font Family
394
+
395
+ Define custom font families and use them with `font-<name>`:
396
+
397
+ ```js
398
+ // kbach.config.js
399
+ module.exports = {
400
+ extend: {
401
+ fontFamily: {
402
+ // shorthand: extend.fontFamily is equivalent to extend.theme.fontFamily
403
+ sans: 'CormorantGaramond_400Regular',
404
+ 'sans-md': 'CormorantGaramond_500Medium',
405
+ 'sans-semi': 'CormorantGaramond_600SemiBold',
406
+ 'sans-bold': 'CormorantGaramond_700Bold',
407
+ },
408
+ },
409
+ };
410
+ ```
411
+
412
+ Use them as utilities:
413
+
414
+ ```jsx
415
+ <Text className="font-sans">Regular</Text>
416
+ <Text className="font-sans-md">Medium</Text>
417
+ <Text className="font-sans-bold">Bold</Text>
418
+ ```
419
+
420
+ **Global default font (web only):** When you set `fontFamily.sans` to anything other than `'System'`, Kbach automatically injects `body { font-family: <your-font> }` into the page — all text inherits it without needing `font-sans` on every element.
421
+
422
+ **React Native:** CSS inheritance does not exist in RN. Apply `font-sans` (or your base font utility) to each `Text` component, or use `styled()` to create a pre-styled text component:
423
+
424
+ ```jsx
425
+ // Define once
426
+ const Body = styled(Text, 'font-sans');
427
+ const Heading = styled(Text, 'font-sans-bold text-2xl');
428
+
429
+ // Use everywhere
430
+ <Body>Regular text</Body>
431
+ <Heading>Title</Heading>
432
+ ```
@@ -8,7 +8,7 @@ import {
8
8
  resolve,
9
9
  useConditionalWidth,
10
10
  useGlobalDarkMode
11
- } from "./chunk-MNDU7U43.mjs";
11
+ } from "./chunk-4R2AILNR.mjs";
12
12
 
13
13
  // src/jsx-runtime.tsx
14
14
  import { jsx as _jsx, jsxs as _jsxs, Fragment } from "react/jsx-runtime";
@@ -2988,6 +2988,10 @@ function getActiveBreakpoints(width) {
2988
2988
 
2989
2989
  // src/core/resolver.ts
2990
2990
  var styleCache = new LRUCache(1e4);
2991
+ var _defaultFontFamily;
2992
+ function setDefaultFontFamily(font) {
2993
+ _defaultFontFamily = font;
2994
+ }
2991
2995
  var _styleEl = null;
2992
2996
  var _injectedRules = /* @__PURE__ */ new Set();
2993
2997
  function getStyleEl() {
@@ -3005,6 +3009,24 @@ function injectRule(rule) {
3005
3009
  } catch {
3006
3010
  }
3007
3011
  }
3012
+ var _globalStyleEl = null;
3013
+ function getGlobalStyleEl() {
3014
+ if (_globalStyleEl) return _globalStyleEl;
3015
+ _globalStyleEl = document.createElement("style");
3016
+ _globalStyleEl.setAttribute("data-kbach-global", "");
3017
+ document.head.insertBefore(_globalStyleEl, getStyleEl());
3018
+ return _globalStyleEl;
3019
+ }
3020
+ function injectGlobalStyles(theme) {
3021
+ if (typeof document === "undefined") return;
3022
+ const rules = [];
3023
+ const ff = theme.fontFamily;
3024
+ if (ff.sans && ff.sans !== "System") {
3025
+ const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
3026
+ rules.push(`body { font-family: ${family}; }`);
3027
+ }
3028
+ getGlobalStyleEl().textContent = rules.join("\n");
3029
+ }
3008
3030
  var MODIFIER_TO_PSEUDO = {
3009
3031
  hover: ":hover",
3010
3032
  focus: ":focus",
@@ -3238,6 +3260,7 @@ function resolve(classString, theme, darkMode = "attribute") {
3238
3260
  }
3239
3261
  function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
3240
3262
  const result = {};
3263
+ if (_defaultFontFamily) result.fontFamily = _defaultFontFamily;
3241
3264
  const entries = Object.entries(resolved);
3242
3265
  entries.sort((a, b) => {
3243
3266
  const pa = a[0] === "base" ? -1 : a[0].split(":").length;
@@ -3414,6 +3437,10 @@ function buildConfig(userConfig) {
3414
3437
  for (const plugin of resolved.plugins) {
3415
3438
  plugin(pluginAPI);
3416
3439
  }
3440
+ const rawSans = theme.fontFamily.sans;
3441
+ const sansFontValue = Array.isArray(rawSans) ? rawSans[0] : rawSans;
3442
+ setDefaultFontFamily(sansFontValue && sansFontValue !== "System" ? sansFontValue : void 0);
3443
+ injectGlobalStyles(resolved.theme);
3417
3444
  return resolved;
3418
3445
  }
3419
3446
  function makePluginAPI(theme) {
package/dist/index.js CHANGED
@@ -3118,6 +3118,10 @@ function getActiveBreakpoints(width) {
3118
3118
 
3119
3119
  // src/core/resolver.ts
3120
3120
  var styleCache = new LRUCache(1e4);
3121
+ var _defaultFontFamily;
3122
+ function setDefaultFontFamily(font) {
3123
+ _defaultFontFamily = font;
3124
+ }
3121
3125
  var _styleEl = null;
3122
3126
  var _injectedRules = /* @__PURE__ */ new Set();
3123
3127
  function getStyleEl() {
@@ -3135,6 +3139,24 @@ function injectRule(rule) {
3135
3139
  } catch {
3136
3140
  }
3137
3141
  }
3142
+ var _globalStyleEl = null;
3143
+ function getGlobalStyleEl() {
3144
+ if (_globalStyleEl) return _globalStyleEl;
3145
+ _globalStyleEl = document.createElement("style");
3146
+ _globalStyleEl.setAttribute("data-kbach-global", "");
3147
+ document.head.insertBefore(_globalStyleEl, getStyleEl());
3148
+ return _globalStyleEl;
3149
+ }
3150
+ function injectGlobalStyles(theme) {
3151
+ if (typeof document === "undefined") return;
3152
+ const rules = [];
3153
+ const ff = theme.fontFamily;
3154
+ if (ff.sans && ff.sans !== "System") {
3155
+ const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
3156
+ rules.push(`body { font-family: ${family}; }`);
3157
+ }
3158
+ getGlobalStyleEl().textContent = rules.join("\n");
3159
+ }
3138
3160
  var MODIFIER_TO_PSEUDO = {
3139
3161
  hover: ":hover",
3140
3162
  focus: ":focus",
@@ -3368,6 +3390,7 @@ function resolve(classString, theme, darkMode = "attribute") {
3368
3390
  }
3369
3391
  function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
3370
3392
  const result = {};
3393
+ if (_defaultFontFamily) result.fontFamily = _defaultFontFamily;
3371
3394
  const entries = Object.entries(resolved);
3372
3395
  entries.sort((a, b) => {
3373
3396
  const pa = a[0] === "base" ? -1 : a[0].split(":").length;
@@ -3544,6 +3567,10 @@ function buildConfig(userConfig) {
3544
3567
  for (const plugin of resolved.plugins) {
3545
3568
  plugin(pluginAPI);
3546
3569
  }
3570
+ const rawSans = theme.fontFamily.sans;
3571
+ const sansFontValue = Array.isArray(rawSans) ? rawSans[0] : rawSans;
3572
+ setDefaultFontFamily(sansFontValue && sansFontValue !== "System" ? sansFontValue : void 0);
3573
+ injectGlobalStyles(resolved.theme);
3547
3574
  return resolved;
3548
3575
  }
3549
3576
  function makePluginAPI(theme) {
package/dist/index.mjs CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  useConditionalWidth,
24
24
  useGlobalDarkMode,
25
25
  useGlobalWidth
26
- } from "./chunk-MNDU7U43.mjs";
26
+ } from "./chunk-4R2AILNR.mjs";
27
27
 
28
28
  // src/context.tsx
29
29
  import { createContext, useContext } from "react";
@@ -3009,6 +3009,10 @@ function getActiveBreakpoints(width) {
3009
3009
 
3010
3010
  // src/core/resolver.ts
3011
3011
  var styleCache = new LRUCache(1e4);
3012
+ var _defaultFontFamily;
3013
+ function setDefaultFontFamily(font) {
3014
+ _defaultFontFamily = font;
3015
+ }
3012
3016
  var _styleEl = null;
3013
3017
  var _injectedRules = /* @__PURE__ */ new Set();
3014
3018
  function getStyleEl() {
@@ -3026,6 +3030,24 @@ function injectRule(rule) {
3026
3030
  } catch {
3027
3031
  }
3028
3032
  }
3033
+ var _globalStyleEl = null;
3034
+ function getGlobalStyleEl() {
3035
+ if (_globalStyleEl) return _globalStyleEl;
3036
+ _globalStyleEl = document.createElement("style");
3037
+ _globalStyleEl.setAttribute("data-kbach-global", "");
3038
+ document.head.insertBefore(_globalStyleEl, getStyleEl());
3039
+ return _globalStyleEl;
3040
+ }
3041
+ function injectGlobalStyles(theme) {
3042
+ if (typeof document === "undefined") return;
3043
+ const rules = [];
3044
+ const ff = theme.fontFamily;
3045
+ if (ff.sans && ff.sans !== "System") {
3046
+ const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
3047
+ rules.push(`body { font-family: ${family}; }`);
3048
+ }
3049
+ getGlobalStyleEl().textContent = rules.join("\n");
3050
+ }
3029
3051
  var MODIFIER_TO_PSEUDO = {
3030
3052
  hover: ":hover",
3031
3053
  focus: ":focus",
@@ -3259,6 +3281,7 @@ function resolve(classString, theme, darkMode = "attribute") {
3259
3281
  }
3260
3282
  function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
3261
3283
  const result = {};
3284
+ if (_defaultFontFamily) result.fontFamily = _defaultFontFamily;
3262
3285
  const entries = Object.entries(resolved);
3263
3286
  entries.sort((a, b) => {
3264
3287
  const pa = a[0] === "base" ? -1 : a[0].split(":").length;
@@ -3427,6 +3450,10 @@ function buildConfig(userConfig) {
3427
3450
  for (const plugin of resolved.plugins) {
3428
3451
  plugin(pluginAPI);
3429
3452
  }
3453
+ const rawSans = theme.fontFamily.sans;
3454
+ const sansFontValue = Array.isArray(rawSans) ? rawSans[0] : rawSans;
3455
+ setDefaultFontFamily(sansFontValue && sansFontValue !== "System" ? sansFontValue : void 0);
3456
+ injectGlobalStyles(resolved.theme);
3430
3457
  return resolved;
3431
3458
  }
3432
3459
  function makePluginAPI(theme) {
@@ -2,8 +2,8 @@ import {
2
2
  Fragment,
3
3
  jsx,
4
4
  jsxs
5
- } from "./chunk-BQJS4P2Z.mjs";
6
- import "./chunk-MNDU7U43.mjs";
5
+ } from "./chunk-3VPBKWUE.mjs";
6
+ import "./chunk-4R2AILNR.mjs";
7
7
 
8
8
  // src/jsx-dev-runtime.tsx
9
9
  function jsxDEV(type, props, key, isStaticChildren, _source, _self) {
@@ -3008,6 +3008,10 @@ function getActiveBreakpoints(width) {
3008
3008
 
3009
3009
  // src/core/resolver.ts
3010
3010
  var styleCache = new LRUCache(1e4);
3011
+ var _defaultFontFamily;
3012
+ function setDefaultFontFamily(font) {
3013
+ _defaultFontFamily = font;
3014
+ }
3011
3015
  var _styleEl = null;
3012
3016
  var _injectedRules = /* @__PURE__ */ new Set();
3013
3017
  function getStyleEl() {
@@ -3025,6 +3029,24 @@ function injectRule(rule) {
3025
3029
  } catch {
3026
3030
  }
3027
3031
  }
3032
+ var _globalStyleEl = null;
3033
+ function getGlobalStyleEl() {
3034
+ if (_globalStyleEl) return _globalStyleEl;
3035
+ _globalStyleEl = document.createElement("style");
3036
+ _globalStyleEl.setAttribute("data-kbach-global", "");
3037
+ document.head.insertBefore(_globalStyleEl, getStyleEl());
3038
+ return _globalStyleEl;
3039
+ }
3040
+ function injectGlobalStyles(theme) {
3041
+ if (typeof document === "undefined") return;
3042
+ const rules = [];
3043
+ const ff = theme.fontFamily;
3044
+ if (ff.sans && ff.sans !== "System") {
3045
+ const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
3046
+ rules.push(`body { font-family: ${family}; }`);
3047
+ }
3048
+ getGlobalStyleEl().textContent = rules.join("\n");
3049
+ }
3028
3050
  var MODIFIER_TO_PSEUDO = {
3029
3051
  hover: ":hover",
3030
3052
  focus: ":focus",
@@ -3258,6 +3280,7 @@ function resolve(classString, theme, darkMode = "attribute") {
3258
3280
  }
3259
3281
  function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
3260
3282
  const result = {};
3283
+ if (_defaultFontFamily) result.fontFamily = _defaultFontFamily;
3261
3284
  const entries = Object.entries(resolved);
3262
3285
  entries.sort((a, b) => {
3263
3286
  const pa = a[0] === "base" ? -1 : a[0].split(":").length;
@@ -3426,6 +3449,10 @@ function buildConfig(userConfig) {
3426
3449
  for (const plugin of resolved.plugins) {
3427
3450
  plugin(pluginAPI);
3428
3451
  }
3452
+ const rawSans = theme.fontFamily.sans;
3453
+ const sansFontValue = Array.isArray(rawSans) ? rawSans[0] : rawSans;
3454
+ setDefaultFontFamily(sansFontValue && sansFontValue !== "System" ? sansFontValue : void 0);
3455
+ injectGlobalStyles(resolved.theme);
3429
3456
  return resolved;
3430
3457
  }
3431
3458
  function makePluginAPI(theme) {
@@ -2,8 +2,8 @@ import {
2
2
  Fragment,
3
3
  jsx,
4
4
  jsxs
5
- } from "./chunk-BQJS4P2Z.mjs";
6
- import "./chunk-MNDU7U43.mjs";
5
+ } from "./chunk-3VPBKWUE.mjs";
6
+ import "./chunk-4R2AILNR.mjs";
7
7
  export {
8
8
  Fragment,
9
9
  jsx,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "React / React Native components and hooks for the Kbach framework",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./dist/index.js",