@kbach/react 0.3.3 → 0.3.5
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-NFPYOE5K.mjs → chunk-2WECG35P.mjs} +71 -15
- package/dist/{chunk-7XL6VQDW.mjs → chunk-6YT4ECUI.mjs} +142 -16
- package/dist/index.d.mts +35 -6
- package/dist/index.d.ts +35 -6
- package/dist/index.js +208 -37
- package/dist/index.mjs +60 -4
- package/dist/jsx-dev-runtime.js +197 -42
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.js +197 -42
- package/dist/jsx-runtime.mjs +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -47,10 +47,12 @@ __export(index_exports, {
|
|
|
47
47
|
resolve: () => resolve,
|
|
48
48
|
styled: () => styled,
|
|
49
49
|
updateConfig: () => updateConfig,
|
|
50
|
+
useBreakpoint: () => useBreakpoint,
|
|
50
51
|
useColors: () => useColors,
|
|
51
52
|
useGlobalDarkMode: () => useGlobalDarkMode,
|
|
52
53
|
useIsDark: () => useIsDark,
|
|
53
54
|
useResolvedStyle: () => useResolvedStyle,
|
|
55
|
+
useResponsive: () => useResponsive,
|
|
54
56
|
useStyles: () => useStyles,
|
|
55
57
|
useTheme: () => useTheme,
|
|
56
58
|
wrapColors: () => wrapColors
|
|
@@ -1966,6 +1968,48 @@ function getPluginStandaloneMap() {
|
|
|
1966
1968
|
return PLUGIN_STANDALONE;
|
|
1967
1969
|
}
|
|
1968
1970
|
|
|
1971
|
+
// src/core/responsiveStore.ts
|
|
1972
|
+
var RESPONSIVE_KEY = "__kbach_responsive__";
|
|
1973
|
+
function getStore() {
|
|
1974
|
+
const g = globalThis;
|
|
1975
|
+
if (!g[RESPONSIVE_KEY]) {
|
|
1976
|
+
g[RESPONSIVE_KEY] = { width: 0, screens: {}, listeners: /* @__PURE__ */ new Set() };
|
|
1977
|
+
}
|
|
1978
|
+
return g[RESPONSIVE_KEY];
|
|
1979
|
+
}
|
|
1980
|
+
function syncGlobalWidth(width) {
|
|
1981
|
+
getStore().width = width;
|
|
1982
|
+
}
|
|
1983
|
+
function syncGlobalScreens(screens) {
|
|
1984
|
+
getStore().screens = screens;
|
|
1985
|
+
}
|
|
1986
|
+
function getGlobalScreens() {
|
|
1987
|
+
return getStore().screens;
|
|
1988
|
+
}
|
|
1989
|
+
function setGlobalWidth(width) {
|
|
1990
|
+
const store = getStore();
|
|
1991
|
+
if (store.width === width) return;
|
|
1992
|
+
store.width = width;
|
|
1993
|
+
for (const l of store.listeners) l(width);
|
|
1994
|
+
}
|
|
1995
|
+
function getGlobalWidth() {
|
|
1996
|
+
return getStore().width;
|
|
1997
|
+
}
|
|
1998
|
+
function subscribeGlobalWidth(listener) {
|
|
1999
|
+
const store = getStore();
|
|
2000
|
+
store.listeners.add(listener);
|
|
2001
|
+
return () => store.listeners.delete(listener);
|
|
2002
|
+
}
|
|
2003
|
+
function getActiveBreakpoints(width) {
|
|
2004
|
+
const store = getStore();
|
|
2005
|
+
const w = width ?? store.width;
|
|
2006
|
+
const active = /* @__PURE__ */ new Set();
|
|
2007
|
+
for (const [name, minW] of Object.entries(store.screens)) {
|
|
2008
|
+
if (typeof minW === "number" && w >= minW) active.add(name);
|
|
2009
|
+
}
|
|
2010
|
+
return active;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
1969
2013
|
// src/core/resolver.ts
|
|
1970
2014
|
var styleCache = new LRUCache(1e4);
|
|
1971
2015
|
var _styleEl = null;
|
|
@@ -2016,6 +2060,7 @@ var GROUP_PEER_PREFIX = {
|
|
|
2016
2060
|
"peer-focus": ".peer:focus ~"
|
|
2017
2061
|
};
|
|
2018
2062
|
var MODE_MODS = /* @__PURE__ */ new Set(["dark", "light", "not-dark", "not-light"]);
|
|
2063
|
+
var RESPONSIVE_MODS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
2019
2064
|
function injectClassRule(cls, bucketKey, styles, darkMode) {
|
|
2020
2065
|
const cssDecls = styleValueToCSS(styles);
|
|
2021
2066
|
if (!cssDecls) return;
|
|
@@ -2025,10 +2070,12 @@ function injectClassRule(cls, bucketKey, styles, darkMode) {
|
|
|
2025
2070
|
return;
|
|
2026
2071
|
}
|
|
2027
2072
|
const mods = bucketKey.split(":");
|
|
2028
|
-
const
|
|
2029
|
-
const
|
|
2030
|
-
const
|
|
2031
|
-
const
|
|
2073
|
+
const responsiveMods = mods.filter((m) => RESPONSIVE_MODS.has(m));
|
|
2074
|
+
const nonResponsiveMods = mods.filter((m) => !RESPONSIVE_MODS.has(m));
|
|
2075
|
+
const hasDark = nonResponsiveMods.includes("dark") || nonResponsiveMods.includes("not-light");
|
|
2076
|
+
const hasLight = nonResponsiveMods.includes("light") || nonResponsiveMods.includes("not-dark");
|
|
2077
|
+
const ancestorMods = nonResponsiveMods.filter((m) => m in GROUP_PEER_PREFIX);
|
|
2078
|
+
const pseudoMods = nonResponsiveMods.filter((m) => !MODE_MODS.has(m) && !(m in GROUP_PEER_PREFIX));
|
|
2032
2079
|
const pseudoSuffix = pseudoMods.map((p) => MODIFIER_TO_PSEUDO[p] ?? `:${p}`).join("");
|
|
2033
2080
|
const elementSelector = `.${escaped}${pseudoSuffix}`;
|
|
2034
2081
|
const ancestorPrefix = ancestorMods.length ? ancestorMods.map((m) => GROUP_PEER_PREFIX[m]).join(" ") + " " : "";
|
|
@@ -2053,6 +2100,13 @@ function injectClassRule(cls, bucketKey, styles, darkMode) {
|
|
|
2053
2100
|
} else {
|
|
2054
2101
|
rule = `${selector} { ${cssDecls} }`;
|
|
2055
2102
|
}
|
|
2103
|
+
if (responsiveMods.length > 0) {
|
|
2104
|
+
const screens = getGlobalScreens();
|
|
2105
|
+
const minWidth = Math.max(...responsiveMods.map((m) => screens[m] ?? 0));
|
|
2106
|
+
if (minWidth > 0) {
|
|
2107
|
+
rule = `@media (min-width: ${minWidth}px) { ${rule} }`;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2056
2110
|
injectRule(rule);
|
|
2057
2111
|
}
|
|
2058
2112
|
var RN_ONLY_PROPS = /* @__PURE__ */ new Set([
|
|
@@ -2121,18 +2175,18 @@ function resolve(classString, theme, darkMode = "attribute") {
|
|
|
2121
2175
|
}
|
|
2122
2176
|
return result;
|
|
2123
2177
|
}
|
|
2124
|
-
function flatten(resolved, isDark, state = {}) {
|
|
2178
|
+
function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
|
|
2125
2179
|
const result = { ...resolved.base ?? {} };
|
|
2126
2180
|
for (const [key, styles] of Object.entries(resolved)) {
|
|
2127
2181
|
if (key === "base" || !styles) continue;
|
|
2128
2182
|
const mods = key.split(":");
|
|
2129
|
-
if (matchesMods(mods, isDark, state)) {
|
|
2183
|
+
if (matchesMods(mods, isDark, state, breakpoints)) {
|
|
2130
2184
|
Object.assign(result, styles);
|
|
2131
2185
|
}
|
|
2132
2186
|
}
|
|
2133
2187
|
return result;
|
|
2134
2188
|
}
|
|
2135
|
-
function matchesMods(mods, isDark, state) {
|
|
2189
|
+
function matchesMods(mods, isDark, state, breakpoints) {
|
|
2136
2190
|
return mods.every((mod) => {
|
|
2137
2191
|
switch (mod) {
|
|
2138
2192
|
case "dark":
|
|
@@ -2170,6 +2224,12 @@ function matchesMods(mods, isDark, state) {
|
|
|
2170
2224
|
return !state.visited;
|
|
2171
2225
|
case "placeholder":
|
|
2172
2226
|
return !!state.placeholder;
|
|
2227
|
+
case "sm":
|
|
2228
|
+
case "md":
|
|
2229
|
+
case "lg":
|
|
2230
|
+
case "xl":
|
|
2231
|
+
case "2xl":
|
|
2232
|
+
return breakpoints.has(mod);
|
|
2173
2233
|
default:
|
|
2174
2234
|
return false;
|
|
2175
2235
|
}
|
|
@@ -2210,6 +2270,28 @@ function getConfig() {
|
|
|
2210
2270
|
store.resolved = buildConfig({});
|
|
2211
2271
|
return store.resolved;
|
|
2212
2272
|
}
|
|
2273
|
+
function resolveOneRef(ref, colors) {
|
|
2274
|
+
const m = /^([a-z][a-z0-9]*)-(\d+)$/.exec(ref);
|
|
2275
|
+
if (!m) return null;
|
|
2276
|
+
const entry = colors[m[1]];
|
|
2277
|
+
if (!entry || typeof entry !== "object") return null;
|
|
2278
|
+
return entry[m[2]] ?? null;
|
|
2279
|
+
}
|
|
2280
|
+
function resolveColorRefs(colors) {
|
|
2281
|
+
const out = {};
|
|
2282
|
+
for (const [key, val] of Object.entries(colors)) {
|
|
2283
|
+
if (typeof val === "string") {
|
|
2284
|
+
out[key] = resolveOneRef(val, colors) ?? val;
|
|
2285
|
+
} else {
|
|
2286
|
+
const shades = {};
|
|
2287
|
+
for (const [shade, hex] of Object.entries(val)) {
|
|
2288
|
+
shades[shade] = resolveOneRef(hex, colors) ?? hex;
|
|
2289
|
+
}
|
|
2290
|
+
out[key] = shades;
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
return out;
|
|
2294
|
+
}
|
|
2213
2295
|
function buildConfig(userConfig) {
|
|
2214
2296
|
let theme = { ...defaultTheme };
|
|
2215
2297
|
if (userConfig.theme) {
|
|
@@ -2228,6 +2310,7 @@ function buildConfig(userConfig) {
|
|
|
2228
2310
|
}
|
|
2229
2311
|
}
|
|
2230
2312
|
}
|
|
2313
|
+
theme = { ...theme, colors: resolveColorRefs(theme.colors) };
|
|
2231
2314
|
const resolved = {
|
|
2232
2315
|
darkMode: userConfig.darkMode ?? "attribute",
|
|
2233
2316
|
theme,
|
|
@@ -2306,7 +2389,7 @@ var customVariants = new Proxy(
|
|
|
2306
2389
|
|
|
2307
2390
|
// src/core/darkModeStore.ts
|
|
2308
2391
|
var KEY = "__kbach_dark_store__";
|
|
2309
|
-
function
|
|
2392
|
+
function getStore2() {
|
|
2310
2393
|
const g = globalThis;
|
|
2311
2394
|
if (!g[KEY]) {
|
|
2312
2395
|
g[KEY] = { isDark: false, lastNotified: false, subscribers: /* @__PURE__ */ new Set() };
|
|
@@ -2314,20 +2397,20 @@ function getStore() {
|
|
|
2314
2397
|
return g[KEY];
|
|
2315
2398
|
}
|
|
2316
2399
|
function syncGlobalDarkMode(isDark) {
|
|
2317
|
-
|
|
2400
|
+
getStore2().isDark = isDark;
|
|
2318
2401
|
}
|
|
2319
2402
|
function setGlobalDarkMode(isDark) {
|
|
2320
|
-
const store =
|
|
2403
|
+
const store = getStore2();
|
|
2321
2404
|
store.isDark = isDark;
|
|
2322
2405
|
if (store.lastNotified === isDark) return;
|
|
2323
2406
|
store.lastNotified = isDark;
|
|
2324
2407
|
for (const sub of store.subscribers) sub();
|
|
2325
2408
|
}
|
|
2326
2409
|
function getGlobalDarkMode() {
|
|
2327
|
-
return
|
|
2410
|
+
return getStore2().isDark;
|
|
2328
2411
|
}
|
|
2329
2412
|
function subscribeGlobalDarkMode(callback) {
|
|
2330
|
-
const store =
|
|
2413
|
+
const store = getStore2();
|
|
2331
2414
|
store.subscribers.add(callback);
|
|
2332
2415
|
return () => store.subscribers.delete(callback);
|
|
2333
2416
|
}
|
|
@@ -2363,12 +2446,36 @@ function ThemeProvider({
|
|
|
2363
2446
|
children,
|
|
2364
2447
|
defaultMode = "system",
|
|
2365
2448
|
colorScheme,
|
|
2449
|
+
windowWidth: windowWidthProp,
|
|
2366
2450
|
config: configOverride,
|
|
2367
2451
|
disablePersistence = false
|
|
2368
2452
|
}) {
|
|
2369
2453
|
const [resolvedConfig, setResolvedConfig] = (0, import_react3.useState)(
|
|
2370
2454
|
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
2371
2455
|
);
|
|
2456
|
+
const [webWidth, setWebWidth] = (0, import_react3.useState)(
|
|
2457
|
+
() => isWeb && typeof window !== "undefined" ? window.innerWidth : 0
|
|
2458
|
+
);
|
|
2459
|
+
const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
|
|
2460
|
+
syncGlobalWidth(effectiveWidth);
|
|
2461
|
+
syncGlobalScreens(resolvedConfig.theme.screens);
|
|
2462
|
+
(0, import_react3.useEffect)(() => {
|
|
2463
|
+
if (!isWeb || typeof window === "undefined") return;
|
|
2464
|
+
let raf = 0;
|
|
2465
|
+
const update = () => {
|
|
2466
|
+
cancelAnimationFrame(raf);
|
|
2467
|
+
raf = requestAnimationFrame(() => {
|
|
2468
|
+
const w = window.innerWidth;
|
|
2469
|
+
setWebWidth(w);
|
|
2470
|
+
setGlobalWidth(w);
|
|
2471
|
+
});
|
|
2472
|
+
};
|
|
2473
|
+
window.addEventListener("resize", update);
|
|
2474
|
+
return () => {
|
|
2475
|
+
window.removeEventListener("resize", update);
|
|
2476
|
+
cancelAnimationFrame(raf);
|
|
2477
|
+
};
|
|
2478
|
+
}, []);
|
|
2372
2479
|
const [webScheme, setWebScheme] = (0, import_react3.useState)(() => {
|
|
2373
2480
|
if (isWeb && typeof window !== "undefined") {
|
|
2374
2481
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
@@ -2637,33 +2744,59 @@ function styled(Component, baseClasses = "") {
|
|
|
2637
2744
|
}
|
|
2638
2745
|
|
|
2639
2746
|
// src/useStyles.ts
|
|
2640
|
-
var
|
|
2747
|
+
var import_react7 = require("react");
|
|
2748
|
+
|
|
2749
|
+
// src/useGlobalWidth.ts
|
|
2750
|
+
var import_react6 = __toESM(require("react"));
|
|
2751
|
+
var useSyncExternalStore = import_react6.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
|
|
2752
|
+
const [, forceUpdate] = import_react6.default.useReducer((n) => n + 1, 0);
|
|
2753
|
+
import_react6.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
|
|
2754
|
+
return getSnapshot();
|
|
2755
|
+
};
|
|
2756
|
+
var NOOP_SUB = (_) => () => {
|
|
2757
|
+
};
|
|
2758
|
+
var ZERO_SNAP = () => 0;
|
|
2759
|
+
var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
|
|
2760
|
+
function useGlobalWidth() {
|
|
2761
|
+
return useSyncExternalStore(subscribeGlobalWidth, getGlobalWidth, ZERO_SNAP);
|
|
2762
|
+
}
|
|
2763
|
+
function useConditionalWidth(active) {
|
|
2764
|
+
return useSyncExternalStore(
|
|
2765
|
+
active ? subscribeGlobalWidth : NOOP_SUB,
|
|
2766
|
+
active ? getGlobalWidth : ZERO_SNAP,
|
|
2767
|
+
ZERO_SNAP
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
// src/useStyles.ts
|
|
2641
2772
|
function useStyles(classString, state = {}) {
|
|
2642
2773
|
const { isDark, config } = useTheme();
|
|
2774
|
+
const width = useGlobalWidth();
|
|
2775
|
+
const breakpoints = isWeb ? EMPTY_BREAKPOINTS : getActiveBreakpoints(width);
|
|
2643
2776
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
2644
|
-
return (0,
|
|
2777
|
+
return (0, import_react7.useMemo)(() => {
|
|
2645
2778
|
const resolved = resolve(normalised, config.theme, config.darkMode);
|
|
2646
|
-
return flatten(resolved, isDark, state);
|
|
2647
|
-
}, [normalised, isDark, config, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
2779
|
+
return flatten(resolved, isDark, state, breakpoints);
|
|
2780
|
+
}, [normalised, isDark, config, width, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
2648
2781
|
}
|
|
2649
2782
|
function useResolvedStyle(classString) {
|
|
2650
2783
|
const { config } = useTheme();
|
|
2651
2784
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
2652
|
-
return (0,
|
|
2785
|
+
return (0, import_react7.useMemo)(
|
|
2653
2786
|
() => resolve(normalised, config.theme, config.darkMode),
|
|
2654
2787
|
[normalised, config]
|
|
2655
2788
|
);
|
|
2656
2789
|
}
|
|
2657
2790
|
|
|
2658
2791
|
// src/useGlobalDarkMode.ts
|
|
2659
|
-
var
|
|
2660
|
-
var
|
|
2661
|
-
const [, forceUpdate] =
|
|
2662
|
-
|
|
2792
|
+
var import_react8 = __toESM(require("react"));
|
|
2793
|
+
var useSyncExternalStore2 = import_react8.default.useSyncExternalStore ?? function useSyncExternalStoreFallback2(subscribe, getSnapshot, _getServerSnapshot) {
|
|
2794
|
+
const [, forceUpdate] = import_react8.default.useReducer((n) => n + 1, 0);
|
|
2795
|
+
import_react8.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
|
|
2663
2796
|
return getSnapshot();
|
|
2664
2797
|
};
|
|
2665
2798
|
function useGlobalDarkMode() {
|
|
2666
|
-
return
|
|
2799
|
+
return useSyncExternalStore2(
|
|
2667
2800
|
subscribeGlobalDarkMode,
|
|
2668
2801
|
getGlobalDarkMode,
|
|
2669
2802
|
() => false
|
|
@@ -2671,15 +2804,47 @@ function useGlobalDarkMode() {
|
|
|
2671
2804
|
);
|
|
2672
2805
|
}
|
|
2673
2806
|
|
|
2807
|
+
// src/useBreakpoint.ts
|
|
2808
|
+
function useBreakpoint() {
|
|
2809
|
+
const { config } = useTheme();
|
|
2810
|
+
const width = useGlobalWidth();
|
|
2811
|
+
const screens = config.theme.screens;
|
|
2812
|
+
const sorted = Object.entries(screens).filter(([, v]) => typeof v === "number").sort(([, a], [, b]) => b - a);
|
|
2813
|
+
for (const [name, minW] of sorted) {
|
|
2814
|
+
if (width >= minW) return name;
|
|
2815
|
+
}
|
|
2816
|
+
return "xs";
|
|
2817
|
+
}
|
|
2818
|
+
function useResponsive() {
|
|
2819
|
+
const { config } = useTheme();
|
|
2820
|
+
const width = useGlobalWidth();
|
|
2821
|
+
const screens = config.theme.screens;
|
|
2822
|
+
const result = {};
|
|
2823
|
+
for (const [name, minW] of Object.entries(screens)) {
|
|
2824
|
+
if (typeof minW === "number") result[name] = width >= minW;
|
|
2825
|
+
}
|
|
2826
|
+
return result;
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2674
2829
|
// src/InteractiveWrapper.tsx
|
|
2675
|
-
var
|
|
2830
|
+
var import_react9 = __toESM(require("react"));
|
|
2676
2831
|
function chain(original, extra) {
|
|
2677
2832
|
return (...args) => {
|
|
2678
2833
|
original?.(...args);
|
|
2679
2834
|
extra();
|
|
2680
2835
|
};
|
|
2681
2836
|
}
|
|
2682
|
-
var
|
|
2837
|
+
var RESPONSIVE_MODS2 = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
2838
|
+
function hasResponsiveBuckets(resolved) {
|
|
2839
|
+
for (const key of Object.keys(resolved)) {
|
|
2840
|
+
if (key === "base") continue;
|
|
2841
|
+
for (const mod of key.split(":")) {
|
|
2842
|
+
if (RESPONSIVE_MODS2.has(mod)) return true;
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
return false;
|
|
2846
|
+
}
|
|
2847
|
+
var InteractiveWrapper = (0, import_react9.forwardRef)(
|
|
2683
2848
|
function InteractiveWrapper2({
|
|
2684
2849
|
Component,
|
|
2685
2850
|
resolvedStyle,
|
|
@@ -2694,18 +2859,22 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
2694
2859
|
...rest
|
|
2695
2860
|
}, ref) {
|
|
2696
2861
|
const isDark = useGlobalDarkMode();
|
|
2697
|
-
const
|
|
2698
|
-
const
|
|
2699
|
-
const
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2702
|
-
const
|
|
2703
|
-
const
|
|
2704
|
-
const
|
|
2705
|
-
const
|
|
2706
|
-
const
|
|
2707
|
-
|
|
2708
|
-
|
|
2862
|
+
const needsWidth = !isWeb && hasResponsiveBuckets(resolvedStyle);
|
|
2863
|
+
const width = useConditionalWidth(needsWidth);
|
|
2864
|
+
const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
|
|
2865
|
+
const [pressed, setPressed] = (0, import_react9.useState)(false);
|
|
2866
|
+
const [hovered, setHovered] = (0, import_react9.useState)(false);
|
|
2867
|
+
const [focused, setFocused] = (0, import_react9.useState)(false);
|
|
2868
|
+
const handlePressIn = (0, import_react9.useCallback)(chain(onPressIn, () => setPressed(true)), [onPressIn]);
|
|
2869
|
+
const handlePressOut = (0, import_react9.useCallback)(chain(onPressOut, () => setPressed(false)), [onPressOut]);
|
|
2870
|
+
const handleMouseEnter = (0, import_react9.useCallback)(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
|
|
2871
|
+
const handleMouseLeave = (0, import_react9.useCallback)(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
|
|
2872
|
+
const handleFocus = (0, import_react9.useCallback)(chain(onFocus, () => setFocused(true)), [onFocus]);
|
|
2873
|
+
const handleBlur = (0, import_react9.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
|
|
2874
|
+
const computedStyle = (0, import_react9.useMemo)(
|
|
2875
|
+
() => flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints),
|
|
2876
|
+
[resolvedStyle, isDark, pressed, hovered, focused, width]
|
|
2877
|
+
// eslint-disable-line react-hooks/exhaustive-deps
|
|
2709
2878
|
);
|
|
2710
2879
|
const finalStyle = styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
|
|
2711
2880
|
const { children, ...restWithoutChildren } = rest;
|
|
@@ -2721,7 +2890,7 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
2721
2890
|
onFocus: handleFocus,
|
|
2722
2891
|
onBlur: handleBlur
|
|
2723
2892
|
};
|
|
2724
|
-
return Array.isArray(children) ?
|
|
2893
|
+
return Array.isArray(children) ? import_react9.default.createElement(Component, componentProps, ...children) : import_react9.default.createElement(Component, componentProps, children);
|
|
2725
2894
|
}
|
|
2726
2895
|
);
|
|
2727
2896
|
InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
|
|
@@ -2757,10 +2926,12 @@ function cx(...classes) {
|
|
|
2757
2926
|
resolve,
|
|
2758
2927
|
styled,
|
|
2759
2928
|
updateConfig,
|
|
2929
|
+
useBreakpoint,
|
|
2760
2930
|
useColors,
|
|
2761
2931
|
useGlobalDarkMode,
|
|
2762
2932
|
useIsDark,
|
|
2763
2933
|
useResolvedStyle,
|
|
2934
|
+
useResponsive,
|
|
2764
2935
|
useStyles,
|
|
2765
2936
|
useTheme,
|
|
2766
2937
|
wrapColors
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
EMPTY_BREAKPOINTS,
|
|
2
3
|
InteractiveWrapper,
|
|
3
4
|
__require,
|
|
4
5
|
buildConfig,
|
|
5
6
|
defaultColors,
|
|
6
7
|
defaultTheme,
|
|
7
8
|
flatten,
|
|
9
|
+
getActiveBreakpoints,
|
|
8
10
|
getConfig,
|
|
9
11
|
initConfig,
|
|
10
12
|
isWeb,
|
|
@@ -13,10 +15,14 @@ import {
|
|
|
13
15
|
parseClasses,
|
|
14
16
|
resolve,
|
|
15
17
|
setGlobalDarkMode,
|
|
18
|
+
setGlobalWidth,
|
|
16
19
|
syncGlobalDarkMode,
|
|
20
|
+
syncGlobalScreens,
|
|
21
|
+
syncGlobalWidth,
|
|
17
22
|
updateConfig,
|
|
18
|
-
useGlobalDarkMode
|
|
19
|
-
|
|
23
|
+
useGlobalDarkMode,
|
|
24
|
+
useGlobalWidth
|
|
25
|
+
} from "./chunk-6YT4ECUI.mjs";
|
|
20
26
|
|
|
21
27
|
// src/context.tsx
|
|
22
28
|
import { createContext, useContext } from "react";
|
|
@@ -129,12 +135,36 @@ function ThemeProvider({
|
|
|
129
135
|
children,
|
|
130
136
|
defaultMode = "system",
|
|
131
137
|
colorScheme,
|
|
138
|
+
windowWidth: windowWidthProp,
|
|
132
139
|
config: configOverride,
|
|
133
140
|
disablePersistence = false
|
|
134
141
|
}) {
|
|
135
142
|
const [resolvedConfig, setResolvedConfig] = useState(
|
|
136
143
|
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
137
144
|
);
|
|
145
|
+
const [webWidth, setWebWidth] = useState(
|
|
146
|
+
() => isWeb && typeof window !== "undefined" ? window.innerWidth : 0
|
|
147
|
+
);
|
|
148
|
+
const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
|
|
149
|
+
syncGlobalWidth(effectiveWidth);
|
|
150
|
+
syncGlobalScreens(resolvedConfig.theme.screens);
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (!isWeb || typeof window === "undefined") return;
|
|
153
|
+
let raf = 0;
|
|
154
|
+
const update = () => {
|
|
155
|
+
cancelAnimationFrame(raf);
|
|
156
|
+
raf = requestAnimationFrame(() => {
|
|
157
|
+
const w = window.innerWidth;
|
|
158
|
+
setWebWidth(w);
|
|
159
|
+
setGlobalWidth(w);
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
window.addEventListener("resize", update);
|
|
163
|
+
return () => {
|
|
164
|
+
window.removeEventListener("resize", update);
|
|
165
|
+
cancelAnimationFrame(raf);
|
|
166
|
+
};
|
|
167
|
+
}, []);
|
|
138
168
|
const [webScheme, setWebScheme] = useState(() => {
|
|
139
169
|
if (isWeb && typeof window !== "undefined") {
|
|
140
170
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
@@ -411,11 +441,13 @@ function styled(Component, baseClasses = "") {
|
|
|
411
441
|
import { useMemo as useMemo4 } from "react";
|
|
412
442
|
function useStyles(classString, state = {}) {
|
|
413
443
|
const { isDark, config } = useTheme();
|
|
444
|
+
const width = useGlobalWidth();
|
|
445
|
+
const breakpoints = isWeb ? EMPTY_BREAKPOINTS : getActiveBreakpoints(width);
|
|
414
446
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
415
447
|
return useMemo4(() => {
|
|
416
448
|
const resolved = resolve(normalised, config.theme, config.darkMode);
|
|
417
|
-
return flatten(resolved, isDark, state);
|
|
418
|
-
}, [normalised, isDark, config, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
449
|
+
return flatten(resolved, isDark, state, breakpoints);
|
|
450
|
+
}, [normalised, isDark, config, width, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
419
451
|
}
|
|
420
452
|
function useResolvedStyle(classString) {
|
|
421
453
|
const { config } = useTheme();
|
|
@@ -426,6 +458,28 @@ function useResolvedStyle(classString) {
|
|
|
426
458
|
);
|
|
427
459
|
}
|
|
428
460
|
|
|
461
|
+
// src/useBreakpoint.ts
|
|
462
|
+
function useBreakpoint() {
|
|
463
|
+
const { config } = useTheme();
|
|
464
|
+
const width = useGlobalWidth();
|
|
465
|
+
const screens = config.theme.screens;
|
|
466
|
+
const sorted = Object.entries(screens).filter(([, v]) => typeof v === "number").sort(([, a], [, b]) => b - a);
|
|
467
|
+
for (const [name, minW] of sorted) {
|
|
468
|
+
if (width >= minW) return name;
|
|
469
|
+
}
|
|
470
|
+
return "xs";
|
|
471
|
+
}
|
|
472
|
+
function useResponsive() {
|
|
473
|
+
const { config } = useTheme();
|
|
474
|
+
const width = useGlobalWidth();
|
|
475
|
+
const screens = config.theme.screens;
|
|
476
|
+
const result = {};
|
|
477
|
+
for (const [name, minW] of Object.entries(screens)) {
|
|
478
|
+
if (typeof minW === "number") result[name] = width >= minW;
|
|
479
|
+
}
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
|
|
429
483
|
// src/kb.ts
|
|
430
484
|
function kb(classString, isDark = false) {
|
|
431
485
|
const config = getConfig();
|
|
@@ -456,10 +510,12 @@ export {
|
|
|
456
510
|
resolve,
|
|
457
511
|
styled,
|
|
458
512
|
updateConfig,
|
|
513
|
+
useBreakpoint,
|
|
459
514
|
useColors,
|
|
460
515
|
useGlobalDarkMode,
|
|
461
516
|
useIsDark,
|
|
462
517
|
useResolvedStyle,
|
|
518
|
+
useResponsive,
|
|
463
519
|
useStyles,
|
|
464
520
|
useTheme,
|
|
465
521
|
wrapColors
|