@kbach/react 0.3.4 → 0.3.6
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-J322Q3UR.mjs → chunk-ALKTUEAA.mjs} +71 -15
- package/dist/{chunk-ADRZPFQC.mjs → chunk-UFSME6UC.mjs} +124 -17
- package/dist/index.d.mts +35 -6
- package/dist/index.d.ts +35 -6
- package/dist/index.js +190 -38
- package/dist/index.mjs +60 -4
- package/dist/jsx-dev-runtime.js +179 -43
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.js +179 -43
- 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
|
|
@@ -635,10 +637,14 @@ var defaultTheme = {
|
|
|
635
637
|
}
|
|
636
638
|
},
|
|
637
639
|
screens: {
|
|
638
|
-
sm:
|
|
640
|
+
sm: 390,
|
|
641
|
+
// large phones (iPhone 12+, most Android flagships)
|
|
639
642
|
md: 768,
|
|
643
|
+
// tablets (iPad and up)
|
|
640
644
|
lg: 1024,
|
|
645
|
+
// large tablets (iPad Pro)
|
|
641
646
|
xl: 1280,
|
|
647
|
+
// desktop
|
|
642
648
|
"2xl": 1536
|
|
643
649
|
}
|
|
644
650
|
};
|
|
@@ -1966,6 +1972,48 @@ function getPluginStandaloneMap() {
|
|
|
1966
1972
|
return PLUGIN_STANDALONE;
|
|
1967
1973
|
}
|
|
1968
1974
|
|
|
1975
|
+
// src/core/responsiveStore.ts
|
|
1976
|
+
var RESPONSIVE_KEY = "__kbach_responsive__";
|
|
1977
|
+
function getStore() {
|
|
1978
|
+
const g = globalThis;
|
|
1979
|
+
if (!g[RESPONSIVE_KEY]) {
|
|
1980
|
+
g[RESPONSIVE_KEY] = { width: 0, screens: {}, listeners: /* @__PURE__ */ new Set() };
|
|
1981
|
+
}
|
|
1982
|
+
return g[RESPONSIVE_KEY];
|
|
1983
|
+
}
|
|
1984
|
+
function syncGlobalWidth(width) {
|
|
1985
|
+
getStore().width = width;
|
|
1986
|
+
}
|
|
1987
|
+
function syncGlobalScreens(screens) {
|
|
1988
|
+
getStore().screens = screens;
|
|
1989
|
+
}
|
|
1990
|
+
function getGlobalScreens() {
|
|
1991
|
+
return getStore().screens;
|
|
1992
|
+
}
|
|
1993
|
+
function setGlobalWidth(width) {
|
|
1994
|
+
const store = getStore();
|
|
1995
|
+
if (store.width === width) return;
|
|
1996
|
+
store.width = width;
|
|
1997
|
+
for (const l of store.listeners) l(width);
|
|
1998
|
+
}
|
|
1999
|
+
function getGlobalWidth() {
|
|
2000
|
+
return getStore().width;
|
|
2001
|
+
}
|
|
2002
|
+
function subscribeGlobalWidth(listener) {
|
|
2003
|
+
const store = getStore();
|
|
2004
|
+
store.listeners.add(listener);
|
|
2005
|
+
return () => store.listeners.delete(listener);
|
|
2006
|
+
}
|
|
2007
|
+
function getActiveBreakpoints(width) {
|
|
2008
|
+
const store = getStore();
|
|
2009
|
+
const w = width ?? store.width;
|
|
2010
|
+
const active = /* @__PURE__ */ new Set();
|
|
2011
|
+
for (const [name, minW] of Object.entries(store.screens)) {
|
|
2012
|
+
if (typeof minW === "number" && w >= minW) active.add(name);
|
|
2013
|
+
}
|
|
2014
|
+
return active;
|
|
2015
|
+
}
|
|
2016
|
+
|
|
1969
2017
|
// src/core/resolver.ts
|
|
1970
2018
|
var styleCache = new LRUCache(1e4);
|
|
1971
2019
|
var _styleEl = null;
|
|
@@ -2016,6 +2064,7 @@ var GROUP_PEER_PREFIX = {
|
|
|
2016
2064
|
"peer-focus": ".peer:focus ~"
|
|
2017
2065
|
};
|
|
2018
2066
|
var MODE_MODS = /* @__PURE__ */ new Set(["dark", "light", "not-dark", "not-light"]);
|
|
2067
|
+
var RESPONSIVE_MODS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
2019
2068
|
function injectClassRule(cls, bucketKey, styles, darkMode) {
|
|
2020
2069
|
const cssDecls = styleValueToCSS(styles);
|
|
2021
2070
|
if (!cssDecls) return;
|
|
@@ -2025,10 +2074,12 @@ function injectClassRule(cls, bucketKey, styles, darkMode) {
|
|
|
2025
2074
|
return;
|
|
2026
2075
|
}
|
|
2027
2076
|
const mods = bucketKey.split(":");
|
|
2028
|
-
const
|
|
2029
|
-
const
|
|
2030
|
-
const
|
|
2031
|
-
const
|
|
2077
|
+
const responsiveMods = mods.filter((m) => RESPONSIVE_MODS.has(m));
|
|
2078
|
+
const nonResponsiveMods = mods.filter((m) => !RESPONSIVE_MODS.has(m));
|
|
2079
|
+
const hasDark = nonResponsiveMods.includes("dark") || nonResponsiveMods.includes("not-light");
|
|
2080
|
+
const hasLight = nonResponsiveMods.includes("light") || nonResponsiveMods.includes("not-dark");
|
|
2081
|
+
const ancestorMods = nonResponsiveMods.filter((m) => m in GROUP_PEER_PREFIX);
|
|
2082
|
+
const pseudoMods = nonResponsiveMods.filter((m) => !MODE_MODS.has(m) && !(m in GROUP_PEER_PREFIX));
|
|
2032
2083
|
const pseudoSuffix = pseudoMods.map((p) => MODIFIER_TO_PSEUDO[p] ?? `:${p}`).join("");
|
|
2033
2084
|
const elementSelector = `.${escaped}${pseudoSuffix}`;
|
|
2034
2085
|
const ancestorPrefix = ancestorMods.length ? ancestorMods.map((m) => GROUP_PEER_PREFIX[m]).join(" ") + " " : "";
|
|
@@ -2053,6 +2104,13 @@ function injectClassRule(cls, bucketKey, styles, darkMode) {
|
|
|
2053
2104
|
} else {
|
|
2054
2105
|
rule = `${selector} { ${cssDecls} }`;
|
|
2055
2106
|
}
|
|
2107
|
+
if (responsiveMods.length > 0) {
|
|
2108
|
+
const screens = getGlobalScreens();
|
|
2109
|
+
const minWidth = Math.max(...responsiveMods.map((m) => screens[m] ?? 0));
|
|
2110
|
+
if (minWidth > 0) {
|
|
2111
|
+
rule = `@media (min-width: ${minWidth}px) { ${rule} }`;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2056
2114
|
injectRule(rule);
|
|
2057
2115
|
}
|
|
2058
2116
|
var RN_ONLY_PROPS = /* @__PURE__ */ new Set([
|
|
@@ -2121,18 +2179,18 @@ function resolve(classString, theme, darkMode = "attribute") {
|
|
|
2121
2179
|
}
|
|
2122
2180
|
return result;
|
|
2123
2181
|
}
|
|
2124
|
-
function flatten(resolved, isDark, state = {}) {
|
|
2182
|
+
function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
|
|
2125
2183
|
const result = { ...resolved.base ?? {} };
|
|
2126
2184
|
for (const [key, styles] of Object.entries(resolved)) {
|
|
2127
2185
|
if (key === "base" || !styles) continue;
|
|
2128
2186
|
const mods = key.split(":");
|
|
2129
|
-
if (matchesMods(mods, isDark, state)) {
|
|
2187
|
+
if (matchesMods(mods, isDark, state, breakpoints)) {
|
|
2130
2188
|
Object.assign(result, styles);
|
|
2131
2189
|
}
|
|
2132
2190
|
}
|
|
2133
2191
|
return result;
|
|
2134
2192
|
}
|
|
2135
|
-
function matchesMods(mods, isDark, state) {
|
|
2193
|
+
function matchesMods(mods, isDark, state, breakpoints) {
|
|
2136
2194
|
return mods.every((mod) => {
|
|
2137
2195
|
switch (mod) {
|
|
2138
2196
|
case "dark":
|
|
@@ -2170,6 +2228,12 @@ function matchesMods(mods, isDark, state) {
|
|
|
2170
2228
|
return !state.visited;
|
|
2171
2229
|
case "placeholder":
|
|
2172
2230
|
return !!state.placeholder;
|
|
2231
|
+
case "sm":
|
|
2232
|
+
case "md":
|
|
2233
|
+
case "lg":
|
|
2234
|
+
case "xl":
|
|
2235
|
+
case "2xl":
|
|
2236
|
+
return breakpoints.has(mod);
|
|
2173
2237
|
default:
|
|
2174
2238
|
return false;
|
|
2175
2239
|
}
|
|
@@ -2329,7 +2393,7 @@ var customVariants = new Proxy(
|
|
|
2329
2393
|
|
|
2330
2394
|
// src/core/darkModeStore.ts
|
|
2331
2395
|
var KEY = "__kbach_dark_store__";
|
|
2332
|
-
function
|
|
2396
|
+
function getStore2() {
|
|
2333
2397
|
const g = globalThis;
|
|
2334
2398
|
if (!g[KEY]) {
|
|
2335
2399
|
g[KEY] = { isDark: false, lastNotified: false, subscribers: /* @__PURE__ */ new Set() };
|
|
@@ -2337,20 +2401,20 @@ function getStore() {
|
|
|
2337
2401
|
return g[KEY];
|
|
2338
2402
|
}
|
|
2339
2403
|
function syncGlobalDarkMode(isDark) {
|
|
2340
|
-
|
|
2404
|
+
getStore2().isDark = isDark;
|
|
2341
2405
|
}
|
|
2342
2406
|
function setGlobalDarkMode(isDark) {
|
|
2343
|
-
const store =
|
|
2407
|
+
const store = getStore2();
|
|
2344
2408
|
store.isDark = isDark;
|
|
2345
2409
|
if (store.lastNotified === isDark) return;
|
|
2346
2410
|
store.lastNotified = isDark;
|
|
2347
2411
|
for (const sub of store.subscribers) sub();
|
|
2348
2412
|
}
|
|
2349
2413
|
function getGlobalDarkMode() {
|
|
2350
|
-
return
|
|
2414
|
+
return getStore2().isDark;
|
|
2351
2415
|
}
|
|
2352
2416
|
function subscribeGlobalDarkMode(callback) {
|
|
2353
|
-
const store =
|
|
2417
|
+
const store = getStore2();
|
|
2354
2418
|
store.subscribers.add(callback);
|
|
2355
2419
|
return () => store.subscribers.delete(callback);
|
|
2356
2420
|
}
|
|
@@ -2386,12 +2450,36 @@ function ThemeProvider({
|
|
|
2386
2450
|
children,
|
|
2387
2451
|
defaultMode = "system",
|
|
2388
2452
|
colorScheme,
|
|
2453
|
+
windowWidth: windowWidthProp,
|
|
2389
2454
|
config: configOverride,
|
|
2390
2455
|
disablePersistence = false
|
|
2391
2456
|
}) {
|
|
2392
2457
|
const [resolvedConfig, setResolvedConfig] = (0, import_react3.useState)(
|
|
2393
2458
|
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
2394
2459
|
);
|
|
2460
|
+
const [webWidth, setWebWidth] = (0, import_react3.useState)(
|
|
2461
|
+
() => isWeb && typeof window !== "undefined" ? window.innerWidth : 0
|
|
2462
|
+
);
|
|
2463
|
+
const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
|
|
2464
|
+
syncGlobalWidth(effectiveWidth);
|
|
2465
|
+
syncGlobalScreens(resolvedConfig.theme.screens);
|
|
2466
|
+
(0, import_react3.useEffect)(() => {
|
|
2467
|
+
if (!isWeb || typeof window === "undefined") return;
|
|
2468
|
+
let raf = 0;
|
|
2469
|
+
const update = () => {
|
|
2470
|
+
cancelAnimationFrame(raf);
|
|
2471
|
+
raf = requestAnimationFrame(() => {
|
|
2472
|
+
const w = window.innerWidth;
|
|
2473
|
+
setWebWidth(w);
|
|
2474
|
+
setGlobalWidth(w);
|
|
2475
|
+
});
|
|
2476
|
+
};
|
|
2477
|
+
window.addEventListener("resize", update);
|
|
2478
|
+
return () => {
|
|
2479
|
+
window.removeEventListener("resize", update);
|
|
2480
|
+
cancelAnimationFrame(raf);
|
|
2481
|
+
};
|
|
2482
|
+
}, []);
|
|
2395
2483
|
const [webScheme, setWebScheme] = (0, import_react3.useState)(() => {
|
|
2396
2484
|
if (isWeb && typeof window !== "undefined") {
|
|
2397
2485
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
@@ -2660,33 +2748,59 @@ function styled(Component, baseClasses = "") {
|
|
|
2660
2748
|
}
|
|
2661
2749
|
|
|
2662
2750
|
// src/useStyles.ts
|
|
2663
|
-
var
|
|
2751
|
+
var import_react7 = require("react");
|
|
2752
|
+
|
|
2753
|
+
// src/useGlobalWidth.ts
|
|
2754
|
+
var import_react6 = __toESM(require("react"));
|
|
2755
|
+
var useSyncExternalStore = import_react6.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
|
|
2756
|
+
const [, forceUpdate] = import_react6.default.useReducer((n) => n + 1, 0);
|
|
2757
|
+
import_react6.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
|
|
2758
|
+
return getSnapshot();
|
|
2759
|
+
};
|
|
2760
|
+
var NOOP_SUB = (_) => () => {
|
|
2761
|
+
};
|
|
2762
|
+
var ZERO_SNAP = () => 0;
|
|
2763
|
+
var EMPTY_BREAKPOINTS = /* @__PURE__ */ new Set();
|
|
2764
|
+
function useGlobalWidth() {
|
|
2765
|
+
return useSyncExternalStore(subscribeGlobalWidth, getGlobalWidth, ZERO_SNAP);
|
|
2766
|
+
}
|
|
2767
|
+
function useConditionalWidth(active) {
|
|
2768
|
+
return useSyncExternalStore(
|
|
2769
|
+
active ? subscribeGlobalWidth : NOOP_SUB,
|
|
2770
|
+
active ? getGlobalWidth : ZERO_SNAP,
|
|
2771
|
+
ZERO_SNAP
|
|
2772
|
+
);
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
// src/useStyles.ts
|
|
2664
2776
|
function useStyles(classString, state = {}) {
|
|
2665
2777
|
const { isDark, config } = useTheme();
|
|
2778
|
+
const width = useGlobalWidth();
|
|
2779
|
+
const breakpoints = isWeb ? EMPTY_BREAKPOINTS : getActiveBreakpoints(width);
|
|
2666
2780
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
2667
|
-
return (0,
|
|
2781
|
+
return (0, import_react7.useMemo)(() => {
|
|
2668
2782
|
const resolved = resolve(normalised, config.theme, config.darkMode);
|
|
2669
|
-
return flatten(resolved, isDark, state);
|
|
2670
|
-
}, [normalised, isDark, config, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
2783
|
+
return flatten(resolved, isDark, state, breakpoints);
|
|
2784
|
+
}, [normalised, isDark, config, width, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
2671
2785
|
}
|
|
2672
2786
|
function useResolvedStyle(classString) {
|
|
2673
2787
|
const { config } = useTheme();
|
|
2674
2788
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
2675
|
-
return (0,
|
|
2789
|
+
return (0, import_react7.useMemo)(
|
|
2676
2790
|
() => resolve(normalised, config.theme, config.darkMode),
|
|
2677
2791
|
[normalised, config]
|
|
2678
2792
|
);
|
|
2679
2793
|
}
|
|
2680
2794
|
|
|
2681
2795
|
// src/useGlobalDarkMode.ts
|
|
2682
|
-
var
|
|
2683
|
-
var
|
|
2684
|
-
const [, forceUpdate] =
|
|
2685
|
-
|
|
2796
|
+
var import_react8 = __toESM(require("react"));
|
|
2797
|
+
var useSyncExternalStore2 = import_react8.default.useSyncExternalStore ?? function useSyncExternalStoreFallback2(subscribe, getSnapshot, _getServerSnapshot) {
|
|
2798
|
+
const [, forceUpdate] = import_react8.default.useReducer((n) => n + 1, 0);
|
|
2799
|
+
import_react8.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
|
|
2686
2800
|
return getSnapshot();
|
|
2687
2801
|
};
|
|
2688
2802
|
function useGlobalDarkMode() {
|
|
2689
|
-
return
|
|
2803
|
+
return useSyncExternalStore2(
|
|
2690
2804
|
subscribeGlobalDarkMode,
|
|
2691
2805
|
getGlobalDarkMode,
|
|
2692
2806
|
() => false
|
|
@@ -2694,15 +2808,47 @@ function useGlobalDarkMode() {
|
|
|
2694
2808
|
);
|
|
2695
2809
|
}
|
|
2696
2810
|
|
|
2811
|
+
// src/useBreakpoint.ts
|
|
2812
|
+
function useBreakpoint() {
|
|
2813
|
+
const { config } = useTheme();
|
|
2814
|
+
const width = useGlobalWidth();
|
|
2815
|
+
const screens = config.theme.screens;
|
|
2816
|
+
const sorted = Object.entries(screens).filter(([, v]) => typeof v === "number").sort(([, a], [, b]) => b - a);
|
|
2817
|
+
for (const [name, minW] of sorted) {
|
|
2818
|
+
if (width >= minW) return name;
|
|
2819
|
+
}
|
|
2820
|
+
return "xs";
|
|
2821
|
+
}
|
|
2822
|
+
function useResponsive() {
|
|
2823
|
+
const { config } = useTheme();
|
|
2824
|
+
const width = useGlobalWidth();
|
|
2825
|
+
const screens = config.theme.screens;
|
|
2826
|
+
const result = {};
|
|
2827
|
+
for (const [name, minW] of Object.entries(screens)) {
|
|
2828
|
+
if (typeof minW === "number") result[name] = width >= minW;
|
|
2829
|
+
}
|
|
2830
|
+
return result;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2697
2833
|
// src/InteractiveWrapper.tsx
|
|
2698
|
-
var
|
|
2834
|
+
var import_react9 = __toESM(require("react"));
|
|
2699
2835
|
function chain(original, extra) {
|
|
2700
2836
|
return (...args) => {
|
|
2701
2837
|
original?.(...args);
|
|
2702
2838
|
extra();
|
|
2703
2839
|
};
|
|
2704
2840
|
}
|
|
2705
|
-
var
|
|
2841
|
+
var RESPONSIVE_MODS2 = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl"]);
|
|
2842
|
+
function hasResponsiveBuckets(resolved) {
|
|
2843
|
+
for (const key of Object.keys(resolved)) {
|
|
2844
|
+
if (key === "base") continue;
|
|
2845
|
+
for (const mod of key.split(":")) {
|
|
2846
|
+
if (RESPONSIVE_MODS2.has(mod)) return true;
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
return false;
|
|
2850
|
+
}
|
|
2851
|
+
var InteractiveWrapper = (0, import_react9.forwardRef)(
|
|
2706
2852
|
function InteractiveWrapper2({
|
|
2707
2853
|
Component,
|
|
2708
2854
|
resolvedStyle,
|
|
@@ -2717,18 +2863,22 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
2717
2863
|
...rest
|
|
2718
2864
|
}, ref) {
|
|
2719
2865
|
const isDark = useGlobalDarkMode();
|
|
2720
|
-
const
|
|
2721
|
-
const
|
|
2722
|
-
const
|
|
2723
|
-
const
|
|
2724
|
-
const
|
|
2725
|
-
const
|
|
2726
|
-
const
|
|
2727
|
-
const
|
|
2728
|
-
const
|
|
2729
|
-
const
|
|
2730
|
-
|
|
2731
|
-
|
|
2866
|
+
const needsWidth = !isWeb && hasResponsiveBuckets(resolvedStyle);
|
|
2867
|
+
const width = useConditionalWidth(needsWidth);
|
|
2868
|
+
const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
|
|
2869
|
+
const [pressed, setPressed] = (0, import_react9.useState)(false);
|
|
2870
|
+
const [hovered, setHovered] = (0, import_react9.useState)(false);
|
|
2871
|
+
const [focused, setFocused] = (0, import_react9.useState)(false);
|
|
2872
|
+
const handlePressIn = (0, import_react9.useCallback)(chain(onPressIn, () => setPressed(true)), [onPressIn]);
|
|
2873
|
+
const handlePressOut = (0, import_react9.useCallback)(chain(onPressOut, () => setPressed(false)), [onPressOut]);
|
|
2874
|
+
const handleMouseEnter = (0, import_react9.useCallback)(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
|
|
2875
|
+
const handleMouseLeave = (0, import_react9.useCallback)(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
|
|
2876
|
+
const handleFocus = (0, import_react9.useCallback)(chain(onFocus, () => setFocused(true)), [onFocus]);
|
|
2877
|
+
const handleBlur = (0, import_react9.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
|
|
2878
|
+
const computedStyle = (0, import_react9.useMemo)(
|
|
2879
|
+
() => flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }, breakpoints),
|
|
2880
|
+
[resolvedStyle, isDark, pressed, hovered, focused, width]
|
|
2881
|
+
// eslint-disable-line react-hooks/exhaustive-deps
|
|
2732
2882
|
);
|
|
2733
2883
|
const finalStyle = styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
|
|
2734
2884
|
const { children, ...restWithoutChildren } = rest;
|
|
@@ -2744,7 +2894,7 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
2744
2894
|
onFocus: handleFocus,
|
|
2745
2895
|
onBlur: handleBlur
|
|
2746
2896
|
};
|
|
2747
|
-
return Array.isArray(children) ?
|
|
2897
|
+
return Array.isArray(children) ? import_react9.default.createElement(Component, componentProps, ...children) : import_react9.default.createElement(Component, componentProps, children);
|
|
2748
2898
|
}
|
|
2749
2899
|
);
|
|
2750
2900
|
InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
|
|
@@ -2780,10 +2930,12 @@ function cx(...classes) {
|
|
|
2780
2930
|
resolve,
|
|
2781
2931
|
styled,
|
|
2782
2932
|
updateConfig,
|
|
2933
|
+
useBreakpoint,
|
|
2783
2934
|
useColors,
|
|
2784
2935
|
useGlobalDarkMode,
|
|
2785
2936
|
useIsDark,
|
|
2786
2937
|
useResolvedStyle,
|
|
2938
|
+
useResponsive,
|
|
2787
2939
|
useStyles,
|
|
2788
2940
|
useTheme,
|
|
2789
2941
|
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-UFSME6UC.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
|