@kbach/react 0.1.0
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-FUSJKUE7.mjs +100 -0
- package/dist/chunk-IZK5HMWK.mjs +85 -0
- package/dist/index.d.mts +185 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +516 -0
- package/dist/index.mjs +421 -0
- package/dist/jsx-dev-runtime.d.mts +19 -0
- package/dist/jsx-dev-runtime.d.ts +19 -0
- package/dist/jsx-dev-runtime.js +211 -0
- package/dist/jsx-dev-runtime.mjs +15 -0
- package/dist/jsx-runtime.d.mts +17 -0
- package/dist/jsx-runtime.d.ts +17 -0
- package/dist/jsx-runtime.js +206 -0
- package/dist/jsx-runtime.mjs +11 -0
- package/package.json +59 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InteractiveWrapper,
|
|
3
|
+
__require,
|
|
4
|
+
useGlobalDarkMode
|
|
5
|
+
} from "./chunk-IZK5HMWK.mjs";
|
|
6
|
+
|
|
7
|
+
// src/context.tsx
|
|
8
|
+
import { createContext, useContext } from "react";
|
|
9
|
+
var ThemeContext = createContext(null);
|
|
10
|
+
function useTheme() {
|
|
11
|
+
const ctx = useContext(ThemeContext);
|
|
12
|
+
if (!ctx) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
"[Kbach] useTheme() must be called inside a <ThemeProvider>. Wrap your app root with <ThemeProvider>."
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/ThemeProvider.tsx
|
|
21
|
+
import {
|
|
22
|
+
useCallback,
|
|
23
|
+
useEffect,
|
|
24
|
+
useMemo,
|
|
25
|
+
useRef,
|
|
26
|
+
useState
|
|
27
|
+
} from "react";
|
|
28
|
+
import {
|
|
29
|
+
isWeb,
|
|
30
|
+
getConfig,
|
|
31
|
+
buildConfig,
|
|
32
|
+
onConfigChange,
|
|
33
|
+
setGlobalDarkMode,
|
|
34
|
+
syncGlobalDarkMode
|
|
35
|
+
} from "@kbach/core";
|
|
36
|
+
import { jsx } from "react/jsx-runtime";
|
|
37
|
+
var Appearance;
|
|
38
|
+
try {
|
|
39
|
+
({ Appearance } = __require("react-native"));
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
var STORAGE_KEY = "kbach-theme";
|
|
43
|
+
function loadPersistedMode() {
|
|
44
|
+
try {
|
|
45
|
+
if (isWeb) {
|
|
46
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function persistMode(mode) {
|
|
54
|
+
try {
|
|
55
|
+
if (isWeb) localStorage.setItem(STORAGE_KEY, mode);
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function applyWebTheme(resolvedMode, strategy) {
|
|
60
|
+
if (!isWeb) return;
|
|
61
|
+
const root = document.documentElement;
|
|
62
|
+
if (strategy === "attribute") {
|
|
63
|
+
root.setAttribute("data-theme", resolvedMode);
|
|
64
|
+
} else if (strategy === "class") {
|
|
65
|
+
root.classList.toggle("dark", resolvedMode === "dark");
|
|
66
|
+
root.classList.toggle("light", resolvedMode === "light");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function ThemeProvider({
|
|
70
|
+
children,
|
|
71
|
+
defaultMode = "system",
|
|
72
|
+
config: configOverride,
|
|
73
|
+
disablePersistence = false
|
|
74
|
+
}) {
|
|
75
|
+
const [resolvedConfig, setResolvedConfig] = useState(
|
|
76
|
+
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
77
|
+
);
|
|
78
|
+
const getSystemScheme = useCallback(() => {
|
|
79
|
+
if (isWeb && typeof window !== "undefined") {
|
|
80
|
+
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
81
|
+
}
|
|
82
|
+
if (Appearance) {
|
|
83
|
+
return Appearance.getColorScheme() === "dark" ? "dark" : "light";
|
|
84
|
+
}
|
|
85
|
+
return "light";
|
|
86
|
+
}, []);
|
|
87
|
+
const [systemScheme, setSystemScheme] = useState(getSystemScheme);
|
|
88
|
+
const [mode, _setMode] = useState(() => {
|
|
89
|
+
if (!disablePersistence) {
|
|
90
|
+
const persisted = loadPersistedMode();
|
|
91
|
+
if (persisted) return persisted;
|
|
92
|
+
}
|
|
93
|
+
return defaultMode;
|
|
94
|
+
});
|
|
95
|
+
const setMode = useCallback((next) => {
|
|
96
|
+
_setMode(next);
|
|
97
|
+
if (!disablePersistence) persistMode(next);
|
|
98
|
+
}, [disablePersistence]);
|
|
99
|
+
const toggle = useCallback(() => {
|
|
100
|
+
setMode(mode === "dark" || mode === "system" && systemScheme === "dark" ? "light" : "dark");
|
|
101
|
+
}, [mode, systemScheme, setMode]);
|
|
102
|
+
const resolvedMode = mode === "system" ? systemScheme : mode;
|
|
103
|
+
const isDark = resolvedMode === "dark";
|
|
104
|
+
syncGlobalDarkMode(isDark);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
applyWebTheme(resolvedMode, resolvedConfig.darkMode);
|
|
107
|
+
setGlobalDarkMode(isDark);
|
|
108
|
+
}, [isDark, resolvedMode, resolvedConfig.darkMode]);
|
|
109
|
+
const setSystemSchemeRef = useRef(setSystemScheme);
|
|
110
|
+
setSystemSchemeRef.current = setSystemScheme;
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (isWeb && typeof window !== "undefined") {
|
|
113
|
+
const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
114
|
+
if (!mq) return;
|
|
115
|
+
const handler = (e) => {
|
|
116
|
+
setSystemSchemeRef.current(e.matches ? "dark" : "light");
|
|
117
|
+
};
|
|
118
|
+
mq.addEventListener("change", handler);
|
|
119
|
+
return () => mq.removeEventListener("change", handler);
|
|
120
|
+
}
|
|
121
|
+
if (Appearance) {
|
|
122
|
+
const sub = Appearance.addChangeListener(({ colorScheme }) => {
|
|
123
|
+
setSystemSchemeRef.current(colorScheme === "dark" ? "dark" : "light");
|
|
124
|
+
});
|
|
125
|
+
return () => sub.remove();
|
|
126
|
+
}
|
|
127
|
+
return void 0;
|
|
128
|
+
}, []);
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (configOverride) return;
|
|
131
|
+
const unsub = onConfigChange(setResolvedConfig);
|
|
132
|
+
return unsub;
|
|
133
|
+
}, [configOverride]);
|
|
134
|
+
const contextValue = useMemo(
|
|
135
|
+
() => ({ mode, resolvedMode, isDark, setMode, toggle, config: resolvedConfig }),
|
|
136
|
+
[mode, resolvedMode, isDark, setMode, toggle, resolvedConfig]
|
|
137
|
+
);
|
|
138
|
+
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/ThemeToggle.tsx
|
|
142
|
+
import React2 from "react";
|
|
143
|
+
function getPrimitives() {
|
|
144
|
+
try {
|
|
145
|
+
const RN = __require("react-native");
|
|
146
|
+
return {
|
|
147
|
+
View: RN.View,
|
|
148
|
+
Text: RN.Text,
|
|
149
|
+
Touchable: RN.TouchableOpacity,
|
|
150
|
+
Switch: RN.Switch
|
|
151
|
+
};
|
|
152
|
+
} catch {
|
|
153
|
+
const View = ({ style, ...rest }) => React2.createElement("div", { style, ...rest });
|
|
154
|
+
const Text = ({ style, ...rest }) => React2.createElement("span", { style, ...rest });
|
|
155
|
+
const Touchable = ({ onPress, style, ...rest }) => React2.createElement("button", { onClick: onPress, style, ...rest });
|
|
156
|
+
const Switch = ({
|
|
157
|
+
value,
|
|
158
|
+
onValueChange,
|
|
159
|
+
accessibilityLabel
|
|
160
|
+
}) => React2.createElement("input", {
|
|
161
|
+
type: "checkbox",
|
|
162
|
+
checked: value,
|
|
163
|
+
onChange: (e) => onValueChange?.(e.target.checked),
|
|
164
|
+
"aria-label": accessibilityLabel
|
|
165
|
+
});
|
|
166
|
+
return { View, Text, Touchable, Switch };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
var { View: _View, Text: _Text, Touchable: _Touchable, Switch: _Switch } = getPrimitives();
|
|
170
|
+
function ThemeToggle({
|
|
171
|
+
variant = "button",
|
|
172
|
+
label,
|
|
173
|
+
lightLabel = "Light",
|
|
174
|
+
darkLabel = "Dark",
|
|
175
|
+
includeSystem = false,
|
|
176
|
+
style,
|
|
177
|
+
labelStyle
|
|
178
|
+
}) {
|
|
179
|
+
const { mode, isDark, setMode, toggle } = useTheme();
|
|
180
|
+
const View = _View, Text = _Text, Touchable = _Touchable, Switch = _Switch;
|
|
181
|
+
if (variant === "switch") {
|
|
182
|
+
return React2.createElement(
|
|
183
|
+
View,
|
|
184
|
+
{ style: { flexDirection: "row", alignItems: "center", gap: 8, ...style } },
|
|
185
|
+
React2.createElement(Text, { style: { fontSize: 14, ...labelStyle } }, lightLabel),
|
|
186
|
+
React2.createElement(Switch, {
|
|
187
|
+
value: isDark,
|
|
188
|
+
onValueChange: (v) => setMode(v ? "dark" : "light"),
|
|
189
|
+
trackColor: { false: "#d1d5db", true: "#6366f1" },
|
|
190
|
+
thumbColor: isDark ? "#ffffff" : "#f3f4f6",
|
|
191
|
+
ios_backgroundColor: "#d1d5db",
|
|
192
|
+
accessibilityLabel: "Toggle dark mode"
|
|
193
|
+
}),
|
|
194
|
+
React2.createElement(Text, { style: { fontSize: 14, ...labelStyle } }, darkLabel)
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
if (variant === "icon-button") {
|
|
198
|
+
const icon = isDark ? darkLabel : lightLabel;
|
|
199
|
+
return React2.createElement(
|
|
200
|
+
Touchable,
|
|
201
|
+
{
|
|
202
|
+
onPress: toggle,
|
|
203
|
+
style: {
|
|
204
|
+
padding: 8,
|
|
205
|
+
borderRadius: 8,
|
|
206
|
+
backgroundColor: isDark ? "#374151" : "#f3f4f6",
|
|
207
|
+
...style
|
|
208
|
+
},
|
|
209
|
+
accessibilityRole: "button",
|
|
210
|
+
accessibilityLabel: `Switch to ${isDark ? "light" : "dark"} mode`,
|
|
211
|
+
accessibilityState: {}
|
|
212
|
+
},
|
|
213
|
+
React2.createElement(Text, { style: { fontSize: 18, ...labelStyle } }, icon)
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (includeSystem) {
|
|
217
|
+
const modes = [
|
|
218
|
+
{ key: "light", label: lightLabel },
|
|
219
|
+
{ key: "dark", label: darkLabel },
|
|
220
|
+
{ key: "system", label: "System" }
|
|
221
|
+
];
|
|
222
|
+
return React2.createElement(
|
|
223
|
+
View,
|
|
224
|
+
{ style: { flexDirection: "row", gap: 4, ...style } },
|
|
225
|
+
...modes.map(
|
|
226
|
+
({ key, label: mLabel }) => React2.createElement(
|
|
227
|
+
Touchable,
|
|
228
|
+
{
|
|
229
|
+
key,
|
|
230
|
+
onPress: () => setMode(key),
|
|
231
|
+
style: {
|
|
232
|
+
paddingHorizontal: 12,
|
|
233
|
+
paddingVertical: 6,
|
|
234
|
+
borderRadius: 6,
|
|
235
|
+
backgroundColor: mode === key ? isDark ? "#6366f1" : "#3b82f6" : isDark ? "#374151" : "#e5e7eb"
|
|
236
|
+
},
|
|
237
|
+
accessibilityRole: "button",
|
|
238
|
+
accessibilityLabel: `Set ${key} theme`,
|
|
239
|
+
accessibilityState: { selected: mode === key }
|
|
240
|
+
},
|
|
241
|
+
React2.createElement(Text, {
|
|
242
|
+
style: {
|
|
243
|
+
fontSize: 13,
|
|
244
|
+
fontWeight: "500",
|
|
245
|
+
color: mode === key ? "#ffffff" : isDark ? "#d1d5db" : "#374151",
|
|
246
|
+
...labelStyle
|
|
247
|
+
}
|
|
248
|
+
}, mLabel)
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
const currentLabel = label ?? (isDark ? darkLabel : lightLabel);
|
|
254
|
+
return React2.createElement(
|
|
255
|
+
Touchable,
|
|
256
|
+
{
|
|
257
|
+
onPress: toggle,
|
|
258
|
+
style: {
|
|
259
|
+
paddingHorizontal: 16,
|
|
260
|
+
paddingVertical: 8,
|
|
261
|
+
borderRadius: 8,
|
|
262
|
+
backgroundColor: isDark ? "#374151" : "#e5e7eb",
|
|
263
|
+
...style
|
|
264
|
+
},
|
|
265
|
+
accessibilityRole: "button",
|
|
266
|
+
accessibilityLabel: `Switch to ${isDark ? "light" : "dark"} mode`,
|
|
267
|
+
accessibilityState: {}
|
|
268
|
+
},
|
|
269
|
+
React2.createElement(Text, {
|
|
270
|
+
style: {
|
|
271
|
+
fontSize: 14,
|
|
272
|
+
fontWeight: "500",
|
|
273
|
+
color: isDark ? "#f9fafb" : "#111827",
|
|
274
|
+
...labelStyle
|
|
275
|
+
}
|
|
276
|
+
}, currentLabel)
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/styled.tsx
|
|
281
|
+
import React3, {
|
|
282
|
+
forwardRef,
|
|
283
|
+
useState as useState2,
|
|
284
|
+
useCallback as useCallback3,
|
|
285
|
+
useMemo as useMemo2
|
|
286
|
+
} from "react";
|
|
287
|
+
import { resolve, flatten } from "@kbach/core";
|
|
288
|
+
function styled(Component, baseClasses = "") {
|
|
289
|
+
const Styled = forwardRef(
|
|
290
|
+
(props, ref) => {
|
|
291
|
+
const {
|
|
292
|
+
tw: extraClasses,
|
|
293
|
+
style: styleProp,
|
|
294
|
+
onPressIn,
|
|
295
|
+
onPressOut,
|
|
296
|
+
onMouseEnter,
|
|
297
|
+
onMouseLeave,
|
|
298
|
+
onFocus,
|
|
299
|
+
onBlur,
|
|
300
|
+
...rest
|
|
301
|
+
} = props;
|
|
302
|
+
const { isDark, config } = useTheme();
|
|
303
|
+
const [pressed, setPressed] = useState2(false);
|
|
304
|
+
const [hovered, setHovered] = useState2(false);
|
|
305
|
+
const [focused, setFocused] = useState2(false);
|
|
306
|
+
const handlePressIn = useCallback3((e) => {
|
|
307
|
+
setPressed(true);
|
|
308
|
+
onPressIn?.(e);
|
|
309
|
+
}, [onPressIn]);
|
|
310
|
+
const handlePressOut = useCallback3((e) => {
|
|
311
|
+
setPressed(false);
|
|
312
|
+
onPressOut?.(e);
|
|
313
|
+
}, [onPressOut]);
|
|
314
|
+
const handleMouseEnter = useCallback3((e) => {
|
|
315
|
+
setHovered(true);
|
|
316
|
+
onMouseEnter?.(e);
|
|
317
|
+
}, [onMouseEnter]);
|
|
318
|
+
const handleMouseLeave = useCallback3((e) => {
|
|
319
|
+
setHovered(false);
|
|
320
|
+
onMouseLeave?.(e);
|
|
321
|
+
}, [onMouseLeave]);
|
|
322
|
+
const handleFocus = useCallback3((e) => {
|
|
323
|
+
setFocused(true);
|
|
324
|
+
onFocus?.(e);
|
|
325
|
+
}, [onFocus]);
|
|
326
|
+
const handleBlur = useCallback3((e) => {
|
|
327
|
+
setFocused(false);
|
|
328
|
+
onBlur?.(e);
|
|
329
|
+
}, [onBlur]);
|
|
330
|
+
const combined = extraClasses ? `${baseClasses} ${extraClasses}` : baseClasses;
|
|
331
|
+
const resolved = useMemo2(() => resolve(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
|
|
332
|
+
const computedStyle = useMemo2(
|
|
333
|
+
() => flatten(resolved, isDark, { pressed, hover: hovered, focus: focused }),
|
|
334
|
+
[resolved, isDark, pressed, hovered, focused]
|
|
335
|
+
);
|
|
336
|
+
const extraStyle = Array.isArray(styleProp) ? Object.assign({}, ...styleProp) : styleProp;
|
|
337
|
+
const finalStyle = extraStyle ? { ...computedStyle, ...extraStyle } : computedStyle;
|
|
338
|
+
return React3.createElement(Component, {
|
|
339
|
+
ref,
|
|
340
|
+
...rest,
|
|
341
|
+
style: finalStyle,
|
|
342
|
+
onPressIn: handlePressIn,
|
|
343
|
+
onPressOut: handlePressOut,
|
|
344
|
+
onMouseEnter: handleMouseEnter,
|
|
345
|
+
onMouseLeave: handleMouseLeave,
|
|
346
|
+
onFocus: handleFocus,
|
|
347
|
+
onBlur: handleBlur
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
const componentName = Component.displayName ?? Component.name ?? "Component";
|
|
352
|
+
Styled.displayName = `Styled(${componentName})`;
|
|
353
|
+
return Styled;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/useStyles.ts
|
|
357
|
+
import { useMemo as useMemo3 } from "react";
|
|
358
|
+
import { resolve as resolve2, flatten as flatten2 } from "@kbach/core";
|
|
359
|
+
function useStyles(classString, state = {}) {
|
|
360
|
+
const { isDark, config } = useTheme();
|
|
361
|
+
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
362
|
+
return useMemo3(() => {
|
|
363
|
+
const resolved = resolve2(normalised, config.theme, config.darkMode);
|
|
364
|
+
return flatten2(resolved, isDark, state);
|
|
365
|
+
}, [normalised, isDark, config, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
366
|
+
}
|
|
367
|
+
function useResolvedStyle(classString) {
|
|
368
|
+
const { config } = useTheme();
|
|
369
|
+
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
370
|
+
return useMemo3(
|
|
371
|
+
() => resolve2(normalised, config.theme, config.darkMode),
|
|
372
|
+
[normalised, config]
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/tw.ts
|
|
377
|
+
import { resolve as resolve3, flatten as flatten3, getConfig as getConfig2, isWeb as isWeb2 } from "@kbach/core";
|
|
378
|
+
function tw(classString, isDark = false) {
|
|
379
|
+
const config = getConfig2();
|
|
380
|
+
const resolved = resolve3(classString, config.theme, config.darkMode);
|
|
381
|
+
if (isWeb2) {
|
|
382
|
+
return classString;
|
|
383
|
+
}
|
|
384
|
+
return flatten3(resolved, isDark);
|
|
385
|
+
}
|
|
386
|
+
function cx(...classes) {
|
|
387
|
+
return classes.filter(Boolean).join(" ");
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// src/index.ts
|
|
391
|
+
import {
|
|
392
|
+
resolve as resolve4,
|
|
393
|
+
flatten as flatten4,
|
|
394
|
+
updateConfig,
|
|
395
|
+
getConfig as getConfig3,
|
|
396
|
+
defaultTheme,
|
|
397
|
+
defaultColors,
|
|
398
|
+
parseClass,
|
|
399
|
+
parseClasses
|
|
400
|
+
} from "@kbach/core";
|
|
401
|
+
export {
|
|
402
|
+
InteractiveWrapper,
|
|
403
|
+
ThemeContext,
|
|
404
|
+
ThemeProvider,
|
|
405
|
+
ThemeToggle,
|
|
406
|
+
cx,
|
|
407
|
+
defaultColors,
|
|
408
|
+
defaultTheme,
|
|
409
|
+
flatten4 as flatten,
|
|
410
|
+
getConfig3 as getConfig,
|
|
411
|
+
parseClass,
|
|
412
|
+
parseClasses,
|
|
413
|
+
resolve4 as resolve,
|
|
414
|
+
styled,
|
|
415
|
+
tw,
|
|
416
|
+
updateConfig,
|
|
417
|
+
useGlobalDarkMode,
|
|
418
|
+
useResolvedStyle,
|
|
419
|
+
useStyles,
|
|
420
|
+
useTheme
|
|
421
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @kbach/react/jsx-dev-runtime
|
|
6
|
+
*
|
|
7
|
+
* Development variant of the custom JSX runtime.
|
|
8
|
+
* Babel uses jsxDEV (instead of jsx/jsxs) in dev builds.
|
|
9
|
+
* We forward isStaticChildren so React's dev-mode key-warning suppression
|
|
10
|
+
* works correctly for compile-time static child arrays.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
declare function jsxDEV(type: unknown, props: Record<string, unknown> | null, key?: string, isStaticChildren?: boolean, _source?: {
|
|
14
|
+
fileName: string;
|
|
15
|
+
lineNumber: number;
|
|
16
|
+
columnNumber: number;
|
|
17
|
+
}, _self?: unknown): ReactElement;
|
|
18
|
+
|
|
19
|
+
export { jsxDEV };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @kbach/react/jsx-dev-runtime
|
|
6
|
+
*
|
|
7
|
+
* Development variant of the custom JSX runtime.
|
|
8
|
+
* Babel uses jsxDEV (instead of jsx/jsxs) in dev builds.
|
|
9
|
+
* We forward isStaticChildren so React's dev-mode key-warning suppression
|
|
10
|
+
* works correctly for compile-time static child arrays.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
declare function jsxDEV(type: unknown, props: Record<string, unknown> | null, key?: string, isStaticChildren?: boolean, _source?: {
|
|
14
|
+
fileName: string;
|
|
15
|
+
lineNumber: number;
|
|
16
|
+
columnNumber: number;
|
|
17
|
+
}, _self?: unknown): ReactElement;
|
|
18
|
+
|
|
19
|
+
export { jsxDEV };
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/jsx-dev-runtime.tsx
|
|
31
|
+
var jsx_dev_runtime_exports = {};
|
|
32
|
+
__export(jsx_dev_runtime_exports, {
|
|
33
|
+
Fragment: () => import_jsx_runtime.Fragment,
|
|
34
|
+
jsxDEV: () => jsxDEV
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(jsx_dev_runtime_exports);
|
|
37
|
+
|
|
38
|
+
// src/jsx-runtime.tsx
|
|
39
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
40
|
+
var import_core4 = require("@kbach/core");
|
|
41
|
+
|
|
42
|
+
// src/InteractiveWrapper.tsx
|
|
43
|
+
var import_react2 = __toESM(require("react"));
|
|
44
|
+
var import_core2 = require("@kbach/core");
|
|
45
|
+
|
|
46
|
+
// src/useGlobalDarkMode.ts
|
|
47
|
+
var import_react = __toESM(require("react"));
|
|
48
|
+
var import_core = require("@kbach/core");
|
|
49
|
+
var useSyncExternalStore = import_react.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, _getServerSnapshot) {
|
|
50
|
+
const [, forceUpdate] = import_react.default.useReducer((n) => n + 1, 0);
|
|
51
|
+
import_react.default.useEffect(() => subscribe(forceUpdate), [subscribe]);
|
|
52
|
+
return getSnapshot();
|
|
53
|
+
};
|
|
54
|
+
function useGlobalDarkMode() {
|
|
55
|
+
return useSyncExternalStore(
|
|
56
|
+
import_core.subscribeGlobalDarkMode,
|
|
57
|
+
import_core.getGlobalDarkMode,
|
|
58
|
+
() => false
|
|
59
|
+
// SSR: default light
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/InteractiveWrapper.tsx
|
|
64
|
+
function chain(original, extra) {
|
|
65
|
+
return (...args) => {
|
|
66
|
+
original?.(...args);
|
|
67
|
+
extra();
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
var InteractiveWrapper = (0, import_react2.forwardRef)(
|
|
71
|
+
function InteractiveWrapper2({
|
|
72
|
+
Component,
|
|
73
|
+
resolvedStyle,
|
|
74
|
+
className,
|
|
75
|
+
style: styleProp,
|
|
76
|
+
onPressIn,
|
|
77
|
+
onPressOut,
|
|
78
|
+
onMouseEnter,
|
|
79
|
+
onMouseLeave,
|
|
80
|
+
onFocus,
|
|
81
|
+
onBlur,
|
|
82
|
+
...rest
|
|
83
|
+
}, ref) {
|
|
84
|
+
const isDark = useGlobalDarkMode();
|
|
85
|
+
const [pressed, setPressed] = (0, import_react2.useState)(false);
|
|
86
|
+
const [hovered, setHovered] = (0, import_react2.useState)(false);
|
|
87
|
+
const [focused, setFocused] = (0, import_react2.useState)(false);
|
|
88
|
+
const handlePressIn = (0, import_react2.useCallback)(chain(onPressIn, () => setPressed(true)), [onPressIn]);
|
|
89
|
+
const handlePressOut = (0, import_react2.useCallback)(chain(onPressOut, () => setPressed(false)), [onPressOut]);
|
|
90
|
+
const handleMouseEnter = (0, import_react2.useCallback)(chain(onMouseEnter, () => setHovered(true)), [onMouseEnter]);
|
|
91
|
+
const handleMouseLeave = (0, import_react2.useCallback)(chain(onMouseLeave, () => setHovered(false)), [onMouseLeave]);
|
|
92
|
+
const handleFocus = (0, import_react2.useCallback)(chain(onFocus, () => setFocused(true)), [onFocus]);
|
|
93
|
+
const handleBlur = (0, import_react2.useCallback)(chain(onBlur, () => setFocused(false)), [onBlur]);
|
|
94
|
+
const computedStyle = (0, import_react2.useMemo)(
|
|
95
|
+
() => (0, import_core2.flatten)(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused }),
|
|
96
|
+
[resolvedStyle, isDark, pressed, hovered, focused]
|
|
97
|
+
);
|
|
98
|
+
const finalStyle = styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
|
|
99
|
+
const { children, ...restWithoutChildren } = rest;
|
|
100
|
+
const componentProps = {
|
|
101
|
+
ref,
|
|
102
|
+
...restWithoutChildren,
|
|
103
|
+
style: finalStyle,
|
|
104
|
+
...import_core2.isWeb && className ? { className } : {},
|
|
105
|
+
onPressIn: handlePressIn,
|
|
106
|
+
onPressOut: handlePressOut,
|
|
107
|
+
onMouseEnter: handleMouseEnter,
|
|
108
|
+
onMouseLeave: handleMouseLeave,
|
|
109
|
+
onFocus: handleFocus,
|
|
110
|
+
onBlur: handleBlur
|
|
111
|
+
};
|
|
112
|
+
return Array.isArray(children) ? import_react2.default.createElement(Component, componentProps, ...children) : import_react2.default.createElement(Component, componentProps, children);
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
|
|
116
|
+
|
|
117
|
+
// src/DarkWrapper.tsx
|
|
118
|
+
var import_react3 = __toESM(require("react"));
|
|
119
|
+
var import_core3 = require("@kbach/core");
|
|
120
|
+
var DarkWrapper = import_react3.default.forwardRef(
|
|
121
|
+
function DarkWrapper2({ Component, resolvedStyle, style: styleProp, children, ...rest }, ref) {
|
|
122
|
+
const isDark = useGlobalDarkMode();
|
|
123
|
+
const computedStyle = (0, import_core3.flatten)(resolvedStyle, isDark);
|
|
124
|
+
const finalStyle = styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
|
|
125
|
+
const props = { ref, ...rest, style: finalStyle };
|
|
126
|
+
return Array.isArray(children) ? import_react3.default.createElement(Component, props, ...children) : import_react3.default.createElement(Component, props, children);
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
DarkWrapper.displayName = "Kbach.DarkWrapper";
|
|
130
|
+
|
|
131
|
+
// src/jsx-runtime.tsx
|
|
132
|
+
var MODE_BUCKET_RE = /^(not-)?(dark|light)(:(not-)?(dark|light))*$/;
|
|
133
|
+
function hasInteractiveBuckets(resolved) {
|
|
134
|
+
return Object.keys(resolved).some((key) => {
|
|
135
|
+
if (key === "base") return false;
|
|
136
|
+
if (/^(sm|md|lg|xl|2xl)$/.test(key)) return false;
|
|
137
|
+
if (MODE_BUCKET_RE.test(key)) return false;
|
|
138
|
+
return true;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
var CONSUMED_PROPS = /* @__PURE__ */ new Set(["className", "tw", "__kbachStyles", "__kbachClasses"]);
|
|
142
|
+
function omitConsumed(props) {
|
|
143
|
+
const out = {};
|
|
144
|
+
for (const key of Object.keys(props)) {
|
|
145
|
+
if (!CONSUMED_PROPS.has(key)) out[key] = props[key];
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
function mergeStyle(computed, userStyle) {
|
|
150
|
+
if (!userStyle) return computed;
|
|
151
|
+
if (Array.isArray(userStyle)) return Object.assign({}, computed, ...userStyle);
|
|
152
|
+
return { ...computed, ...userStyle };
|
|
153
|
+
}
|
|
154
|
+
function makeElement(isStaticChildren, type, props, key) {
|
|
155
|
+
return (isStaticChildren ? import_jsx_runtime.jsxs : import_jsx_runtime.jsx)(type, props, key);
|
|
156
|
+
}
|
|
157
|
+
function processElement(type, rawProps, key, isStaticChildren) {
|
|
158
|
+
if (!rawProps) return (0, import_jsx_runtime.jsx)(type, null, key);
|
|
159
|
+
const { className, tw: twProp, __kbachStyles, __kbachClasses } = rawProps;
|
|
160
|
+
const classStr = className ?? twProp ?? __kbachClasses;
|
|
161
|
+
if (!classStr && !__kbachStyles) {
|
|
162
|
+
return makeElement(isStaticChildren, type, rawProps, key);
|
|
163
|
+
}
|
|
164
|
+
const config = (0, import_core4.getConfig)();
|
|
165
|
+
const resolved = __kbachStyles ?? (classStr ? (0, import_core4.resolve)(classStr, config.theme, config.darkMode) : {});
|
|
166
|
+
const { style: userStyle, ...passProps } = omitConsumed(rawProps);
|
|
167
|
+
if (hasInteractiveBuckets(resolved)) {
|
|
168
|
+
return (0, import_jsx_runtime.jsx)(InteractiveWrapper, {
|
|
169
|
+
Component: type,
|
|
170
|
+
resolvedStyle: resolved,
|
|
171
|
+
...import_core4.isWeb && classStr ? { className: classStr } : {},
|
|
172
|
+
style: userStyle,
|
|
173
|
+
...passProps
|
|
174
|
+
}, key);
|
|
175
|
+
}
|
|
176
|
+
const hasModeVariants = Object.keys(resolved).some(
|
|
177
|
+
(k) => k !== "base" && MODE_BUCKET_RE.test(k)
|
|
178
|
+
);
|
|
179
|
+
if (hasModeVariants) {
|
|
180
|
+
return (0, import_jsx_runtime.jsx)(DarkWrapper, {
|
|
181
|
+
Component: type,
|
|
182
|
+
resolvedStyle: resolved,
|
|
183
|
+
...import_core4.isWeb && classStr ? { className: classStr } : {},
|
|
184
|
+
style: userStyle,
|
|
185
|
+
...passProps
|
|
186
|
+
}, key);
|
|
187
|
+
}
|
|
188
|
+
const computedStyle = (0, import_core4.flatten)(resolved, false);
|
|
189
|
+
const finalStyle = mergeStyle(computedStyle, userStyle);
|
|
190
|
+
return makeElement(isStaticChildren, type, {
|
|
191
|
+
...passProps,
|
|
192
|
+
style: finalStyle,
|
|
193
|
+
...import_core4.isWeb && classStr ? { className: classStr } : {}
|
|
194
|
+
}, key);
|
|
195
|
+
}
|
|
196
|
+
function jsx(type, props, key) {
|
|
197
|
+
return processElement(type, props, key, false);
|
|
198
|
+
}
|
|
199
|
+
function jsxs(type, props, key) {
|
|
200
|
+
return processElement(type, props, key, true);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/jsx-dev-runtime.tsx
|
|
204
|
+
function jsxDEV(type, props, key, isStaticChildren, _source, _self) {
|
|
205
|
+
return (isStaticChildren ? jsxs : jsx)(type, props, key);
|
|
206
|
+
}
|
|
207
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
208
|
+
0 && (module.exports = {
|
|
209
|
+
Fragment,
|
|
210
|
+
jsxDEV
|
|
211
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Fragment,
|
|
3
|
+
jsx,
|
|
4
|
+
jsxs
|
|
5
|
+
} from "./chunk-FUSJKUE7.mjs";
|
|
6
|
+
import "./chunk-IZK5HMWK.mjs";
|
|
7
|
+
|
|
8
|
+
// src/jsx-dev-runtime.tsx
|
|
9
|
+
function jsxDEV(type, props, key, isStaticChildren, _source, _self) {
|
|
10
|
+
return (isStaticChildren ? jsxs : jsx)(type, props, key);
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
Fragment,
|
|
14
|
+
jsxDEV
|
|
15
|
+
};
|