@kbach/react 0.6.25 → 0.6.26
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 +53 -27
- package/dist/{chunk-XISB5W3A.mjs → chunk-AKX6I7WP.mjs} +1301 -1297
- package/dist/{chunk-RUI5EQDF.mjs → chunk-NWQIZZCW.mjs} +6 -2
- package/dist/core/index.d.ts +1274 -0
- package/dist/core/index.js +3457 -0
- package/dist/index.d.ts +50 -224
- package/dist/index.js +215 -3445
- package/dist/index.mjs +77 -36
- package/dist/jsx-dev-runtime.js +54 -3279
- package/dist/jsx-dev-runtime.mjs +2 -2
- package/dist/jsx-runtime.js +54 -3279
- package/dist/jsx-runtime.mjs +2 -2
- package/dist/vite-plugin.js +1348 -1292
- package/dist/vite-plugin.mjs +1348 -1292
- package/kbach-react.md +15 -1
- package/package.json +4 -8
- package/dist/index.d.mts +0 -455
- package/dist/jsx-dev-runtime.d.mts +0 -21
- package/dist/jsx-runtime.d.mts +0 -17
- package/dist/vite-plugin-client.d.mts +0 -8
- package/dist/vite-plugin-client.d.ts +0 -8
- package/dist/web-substitute-CfpYFnE7.d.mts +0 -22
package/dist/index.js
CHANGED
|
@@ -35,34 +35,36 @@ __export(index_exports, {
|
|
|
35
35
|
KbachReset: () => KbachReset,
|
|
36
36
|
ThemeContext: () => ThemeContext,
|
|
37
37
|
ThemeProvider: () => ThemeProvider,
|
|
38
|
-
buildConfig: () => buildConfig,
|
|
39
|
-
clearCache: () => clearCache,
|
|
38
|
+
buildConfig: () => import_core12.buildConfig,
|
|
39
|
+
clearCache: () => import_core12.clearCache,
|
|
40
40
|
cx: () => cx,
|
|
41
|
-
defaultColors: () => defaultColors,
|
|
42
|
-
defaultTheme: () => defaultTheme,
|
|
43
|
-
disableRuntimeCSS: () => disableRuntimeCSS,
|
|
44
|
-
flatten: () => flatten,
|
|
45
|
-
getConfig: () => getConfig,
|
|
46
|
-
initConfig: () => initConfig,
|
|
41
|
+
defaultColors: () => import_core12.defaultColors,
|
|
42
|
+
defaultTheme: () => import_core12.defaultTheme,
|
|
43
|
+
disableRuntimeCSS: () => import_core12.disableRuntimeCSS,
|
|
44
|
+
flatten: () => import_core12.flatten,
|
|
45
|
+
getConfig: () => import_core12.getConfig,
|
|
46
|
+
initConfig: () => import_core12.initConfig,
|
|
47
47
|
kb: () => kb,
|
|
48
|
-
normalizeClassString: () => normalizeClassString,
|
|
49
|
-
parseClass: () => parseClass,
|
|
50
|
-
parseClasses: () => parseClasses,
|
|
48
|
+
normalizeClassString: () => import_core12.normalizeClassString,
|
|
49
|
+
parseClass: () => import_core12.parseClass,
|
|
50
|
+
parseClasses: () => import_core12.parseClasses,
|
|
51
51
|
registerWebElement: () => registerWebElement,
|
|
52
|
-
resolve: () => resolve,
|
|
53
|
-
setResolveTarget: () => setResolveTarget,
|
|
54
|
-
splitClassTokens: () => splitClassTokens,
|
|
52
|
+
resolve: () => import_core12.resolve,
|
|
53
|
+
setResolveTarget: () => import_core12.setResolveTarget,
|
|
54
|
+
splitClassTokens: () => import_core12.splitClassTokens,
|
|
55
55
|
styled: () => styled,
|
|
56
|
-
updateConfig: () => updateConfig,
|
|
56
|
+
updateConfig: () => import_core12.updateConfig,
|
|
57
57
|
useBreakpoint: () => useBreakpoint,
|
|
58
58
|
useColors: () => useColors,
|
|
59
59
|
useGlobalDarkMode: () => useGlobalDarkMode,
|
|
60
60
|
useIsDark: () => useIsDark,
|
|
61
61
|
useResolvedStyle: () => useResolvedStyle,
|
|
62
62
|
useResponsive: () => useResponsive,
|
|
63
|
+
useSpacing: () => useSpacing,
|
|
63
64
|
useStyles: () => useStyles,
|
|
64
65
|
useTheme: () => useTheme,
|
|
65
|
-
wrapColors: () => wrapColors
|
|
66
|
+
wrapColors: () => wrapColors,
|
|
67
|
+
wrapSpacing: () => wrapSpacing
|
|
66
68
|
});
|
|
67
69
|
module.exports = __toCommonJS(index_exports);
|
|
68
70
|
|
|
@@ -84,3303 +86,11 @@ function useIsDark() {
|
|
|
84
86
|
|
|
85
87
|
// src/useColors.ts
|
|
86
88
|
var import_react2 = require("react");
|
|
87
|
-
|
|
88
|
-
// src/core/theme.ts
|
|
89
|
-
var defaultColors = {
|
|
90
|
-
transparent: "transparent",
|
|
91
|
-
current: "currentColor",
|
|
92
|
-
black: "#000000",
|
|
93
|
-
white: "#ffffff",
|
|
94
|
-
slate: {
|
|
95
|
-
1: "#f8fafc",
|
|
96
|
-
2: "#f1f5f9",
|
|
97
|
-
3: "#e2e8f0",
|
|
98
|
-
4: "#cbd5e1",
|
|
99
|
-
5: "#94a3b8",
|
|
100
|
-
6: "#64748b",
|
|
101
|
-
7: "#475569",
|
|
102
|
-
8: "#334155",
|
|
103
|
-
9: "#1e293b",
|
|
104
|
-
10: "#0f172a",
|
|
105
|
-
11: "#020617",
|
|
106
|
-
12: "#01020a"
|
|
107
|
-
},
|
|
108
|
-
gray: {
|
|
109
|
-
1: "#f9fafb",
|
|
110
|
-
2: "#f3f4f6",
|
|
111
|
-
3: "#e5e7eb",
|
|
112
|
-
4: "#d1d5db",
|
|
113
|
-
5: "#9ca3af",
|
|
114
|
-
6: "#6b7280",
|
|
115
|
-
7: "#4b5563",
|
|
116
|
-
8: "#374151",
|
|
117
|
-
9: "#1f2937",
|
|
118
|
-
10: "#111827",
|
|
119
|
-
11: "#030712",
|
|
120
|
-
12: "#020409"
|
|
121
|
-
},
|
|
122
|
-
zinc: {
|
|
123
|
-
1: "#fafafa",
|
|
124
|
-
2: "#f4f4f5",
|
|
125
|
-
3: "#e4e4e7",
|
|
126
|
-
4: "#d4d4d8",
|
|
127
|
-
5: "#a1a1aa",
|
|
128
|
-
6: "#71717a",
|
|
129
|
-
7: "#52525b",
|
|
130
|
-
8: "#3f3f46",
|
|
131
|
-
9: "#27272a",
|
|
132
|
-
10: "#18181b",
|
|
133
|
-
11: "#09090b",
|
|
134
|
-
12: "#050506"
|
|
135
|
-
},
|
|
136
|
-
neutral: {
|
|
137
|
-
1: "#fafafa",
|
|
138
|
-
2: "#f5f5f5",
|
|
139
|
-
3: "#e5e5e5",
|
|
140
|
-
4: "#d4d4d4",
|
|
141
|
-
5: "#a3a3a3",
|
|
142
|
-
6: "#737373",
|
|
143
|
-
7: "#525252",
|
|
144
|
-
8: "#404040",
|
|
145
|
-
9: "#262626",
|
|
146
|
-
10: "#171717",
|
|
147
|
-
11: "#0a0a0a",
|
|
148
|
-
12: "#050505"
|
|
149
|
-
},
|
|
150
|
-
stone: {
|
|
151
|
-
1: "#fafaf9",
|
|
152
|
-
2: "#f5f5f4",
|
|
153
|
-
3: "#e7e5e4",
|
|
154
|
-
4: "#d6d3d1",
|
|
155
|
-
5: "#a8a29e",
|
|
156
|
-
6: "#78716c",
|
|
157
|
-
7: "#57534e",
|
|
158
|
-
8: "#44403c",
|
|
159
|
-
9: "#292524",
|
|
160
|
-
10: "#1c1917",
|
|
161
|
-
11: "#0c0a09",
|
|
162
|
-
12: "#070605"
|
|
163
|
-
},
|
|
164
|
-
red: {
|
|
165
|
-
1: "#fef2f2",
|
|
166
|
-
2: "#fee2e2",
|
|
167
|
-
3: "#fecaca",
|
|
168
|
-
4: "#fca5a5",
|
|
169
|
-
5: "#f87171",
|
|
170
|
-
6: "#ef4444",
|
|
171
|
-
7: "#dc2626",
|
|
172
|
-
8: "#b91c1c",
|
|
173
|
-
9: "#991b1b",
|
|
174
|
-
10: "#7f1d1d",
|
|
175
|
-
11: "#450a0a",
|
|
176
|
-
12: "#280606"
|
|
177
|
-
},
|
|
178
|
-
orange: {
|
|
179
|
-
1: "#fff7ed",
|
|
180
|
-
2: "#ffedd5",
|
|
181
|
-
3: "#fed7aa",
|
|
182
|
-
4: "#fdba74",
|
|
183
|
-
5: "#fb923c",
|
|
184
|
-
6: "#f97316",
|
|
185
|
-
7: "#ea580c",
|
|
186
|
-
8: "#c2410c",
|
|
187
|
-
9: "#9a3412",
|
|
188
|
-
10: "#7c2d12",
|
|
189
|
-
11: "#431407",
|
|
190
|
-
12: "#270c04"
|
|
191
|
-
},
|
|
192
|
-
amber: {
|
|
193
|
-
1: "#fffbeb",
|
|
194
|
-
2: "#fef3c7",
|
|
195
|
-
3: "#fde68a",
|
|
196
|
-
4: "#fcd34d",
|
|
197
|
-
5: "#fbbf24",
|
|
198
|
-
6: "#f59e0b",
|
|
199
|
-
7: "#d97706",
|
|
200
|
-
8: "#b45309",
|
|
201
|
-
9: "#92400e",
|
|
202
|
-
10: "#78350f",
|
|
203
|
-
11: "#451a03",
|
|
204
|
-
12: "#291002"
|
|
205
|
-
},
|
|
206
|
-
yellow: {
|
|
207
|
-
1: "#fefce8",
|
|
208
|
-
2: "#fef9c3",
|
|
209
|
-
3: "#fef08a",
|
|
210
|
-
4: "#fde047",
|
|
211
|
-
5: "#facc15",
|
|
212
|
-
6: "#eab308",
|
|
213
|
-
7: "#ca8a04",
|
|
214
|
-
8: "#a16207",
|
|
215
|
-
9: "#854d0e",
|
|
216
|
-
10: "#713f12",
|
|
217
|
-
11: "#422006",
|
|
218
|
-
12: "#271304"
|
|
219
|
-
},
|
|
220
|
-
lime: {
|
|
221
|
-
1: "#f7fee7",
|
|
222
|
-
2: "#ecfccb",
|
|
223
|
-
3: "#d9f99d",
|
|
224
|
-
4: "#bef264",
|
|
225
|
-
5: "#a3e635",
|
|
226
|
-
6: "#84cc16",
|
|
227
|
-
7: "#65a30d",
|
|
228
|
-
8: "#4d7c0f",
|
|
229
|
-
9: "#3f6212",
|
|
230
|
-
10: "#365314",
|
|
231
|
-
11: "#1a2e05",
|
|
232
|
-
12: "#0f1b03"
|
|
233
|
-
},
|
|
234
|
-
green: {
|
|
235
|
-
1: "#f0fdf4",
|
|
236
|
-
2: "#dcfce7",
|
|
237
|
-
3: "#bbf7d0",
|
|
238
|
-
4: "#86efac",
|
|
239
|
-
5: "#4ade80",
|
|
240
|
-
6: "#22c55e",
|
|
241
|
-
7: "#16a34a",
|
|
242
|
-
8: "#15803d",
|
|
243
|
-
9: "#166534",
|
|
244
|
-
10: "#14532d",
|
|
245
|
-
11: "#052e16",
|
|
246
|
-
12: "#031b0d"
|
|
247
|
-
},
|
|
248
|
-
emerald: {
|
|
249
|
-
1: "#ecfdf5",
|
|
250
|
-
2: "#d1fae5",
|
|
251
|
-
3: "#a7f3d0",
|
|
252
|
-
4: "#6ee7b7",
|
|
253
|
-
5: "#34d399",
|
|
254
|
-
6: "#10b981",
|
|
255
|
-
7: "#059669",
|
|
256
|
-
8: "#047857",
|
|
257
|
-
9: "#065f46",
|
|
258
|
-
10: "#064e3b",
|
|
259
|
-
11: "#022c22",
|
|
260
|
-
12: "#011a14"
|
|
261
|
-
},
|
|
262
|
-
teal: {
|
|
263
|
-
1: "#f0fdfa",
|
|
264
|
-
2: "#ccfbf1",
|
|
265
|
-
3: "#99f6e4",
|
|
266
|
-
4: "#5eead4",
|
|
267
|
-
5: "#2dd4bf",
|
|
268
|
-
6: "#14b8a6",
|
|
269
|
-
7: "#0d9488",
|
|
270
|
-
8: "#0f766e",
|
|
271
|
-
9: "#115e59",
|
|
272
|
-
10: "#134e4a",
|
|
273
|
-
11: "#042f2e",
|
|
274
|
-
12: "#021c1b"
|
|
275
|
-
},
|
|
276
|
-
cyan: {
|
|
277
|
-
1: "#ecfeff",
|
|
278
|
-
2: "#cffafe",
|
|
279
|
-
3: "#a5f3fc",
|
|
280
|
-
4: "#67e8f9",
|
|
281
|
-
5: "#22d3ee",
|
|
282
|
-
6: "#06b6d4",
|
|
283
|
-
7: "#0891b2",
|
|
284
|
-
8: "#0e7490",
|
|
285
|
-
9: "#155e75",
|
|
286
|
-
10: "#164e63",
|
|
287
|
-
11: "#083344",
|
|
288
|
-
12: "#041e28"
|
|
289
|
-
},
|
|
290
|
-
sky: {
|
|
291
|
-
1: "#f0f9ff",
|
|
292
|
-
2: "#e0f2fe",
|
|
293
|
-
3: "#bae6fd",
|
|
294
|
-
4: "#7dd3fc",
|
|
295
|
-
5: "#38bdf8",
|
|
296
|
-
6: "#0ea5e9",
|
|
297
|
-
7: "#0284c7",
|
|
298
|
-
8: "#0369a1",
|
|
299
|
-
9: "#075985",
|
|
300
|
-
10: "#0c4a6e",
|
|
301
|
-
11: "#082f49",
|
|
302
|
-
12: "#041b2b"
|
|
303
|
-
},
|
|
304
|
-
blue: {
|
|
305
|
-
1: "#eff6ff",
|
|
306
|
-
2: "#dbeafe",
|
|
307
|
-
3: "#bfdbfe",
|
|
308
|
-
4: "#93c5fd",
|
|
309
|
-
5: "#60a5fa",
|
|
310
|
-
6: "#3b82f6",
|
|
311
|
-
7: "#2563eb",
|
|
312
|
-
8: "#1d4ed8",
|
|
313
|
-
9: "#1e40af",
|
|
314
|
-
10: "#1e3a8a",
|
|
315
|
-
11: "#172554",
|
|
316
|
-
12: "#0d1633"
|
|
317
|
-
},
|
|
318
|
-
indigo: {
|
|
319
|
-
1: "#eef2ff",
|
|
320
|
-
2: "#e0e7ff",
|
|
321
|
-
3: "#c7d2fe",
|
|
322
|
-
4: "#a5b4fc",
|
|
323
|
-
5: "#818cf8",
|
|
324
|
-
6: "#6366f1",
|
|
325
|
-
7: "#4f46e5",
|
|
326
|
-
8: "#4338ca",
|
|
327
|
-
9: "#3730a3",
|
|
328
|
-
10: "#312e81",
|
|
329
|
-
11: "#1e1b4b",
|
|
330
|
-
12: "#12102d"
|
|
331
|
-
},
|
|
332
|
-
violet: {
|
|
333
|
-
1: "#f5f3ff",
|
|
334
|
-
2: "#ede9fe",
|
|
335
|
-
3: "#ddd6fe",
|
|
336
|
-
4: "#c4b5fd",
|
|
337
|
-
5: "#a78bfa",
|
|
338
|
-
6: "#8b5cf6",
|
|
339
|
-
7: "#7c3aed",
|
|
340
|
-
8: "#6d28d9",
|
|
341
|
-
9: "#5b21b6",
|
|
342
|
-
10: "#4c1d95",
|
|
343
|
-
11: "#2e1065",
|
|
344
|
-
12: "#1c0a3d"
|
|
345
|
-
},
|
|
346
|
-
purple: {
|
|
347
|
-
1: "#faf5ff",
|
|
348
|
-
2: "#f3e8ff",
|
|
349
|
-
3: "#e9d5ff",
|
|
350
|
-
4: "#d8b4fe",
|
|
351
|
-
5: "#c084fc",
|
|
352
|
-
6: "#a855f7",
|
|
353
|
-
7: "#9333ea",
|
|
354
|
-
8: "#7e22ce",
|
|
355
|
-
9: "#6b21a8",
|
|
356
|
-
10: "#581c87",
|
|
357
|
-
11: "#3b0764",
|
|
358
|
-
12: "#23043c"
|
|
359
|
-
},
|
|
360
|
-
fuchsia: {
|
|
361
|
-
1: "#fdf4ff",
|
|
362
|
-
2: "#fae8ff",
|
|
363
|
-
3: "#f5d0fe",
|
|
364
|
-
4: "#f0abfc",
|
|
365
|
-
5: "#e879f9",
|
|
366
|
-
6: "#d946ef",
|
|
367
|
-
7: "#c026d3",
|
|
368
|
-
8: "#a21caf",
|
|
369
|
-
9: "#86198f",
|
|
370
|
-
10: "#701a75",
|
|
371
|
-
11: "#4a044e",
|
|
372
|
-
12: "#2d022f"
|
|
373
|
-
},
|
|
374
|
-
pink: {
|
|
375
|
-
1: "#fdf2f8",
|
|
376
|
-
2: "#fce7f3",
|
|
377
|
-
3: "#fbcfe8",
|
|
378
|
-
4: "#f9a8d4",
|
|
379
|
-
5: "#f472b6",
|
|
380
|
-
6: "#ec4899",
|
|
381
|
-
7: "#db2777",
|
|
382
|
-
8: "#be185d",
|
|
383
|
-
9: "#9d174d",
|
|
384
|
-
10: "#831843",
|
|
385
|
-
11: "#500724",
|
|
386
|
-
12: "#300415"
|
|
387
|
-
},
|
|
388
|
-
rose: {
|
|
389
|
-
1: "#fff1f2",
|
|
390
|
-
2: "#ffe4e6",
|
|
391
|
-
3: "#fecdd3",
|
|
392
|
-
4: "#fda4af",
|
|
393
|
-
5: "#fb7185",
|
|
394
|
-
6: "#f43f5e",
|
|
395
|
-
7: "#e11d48",
|
|
396
|
-
8: "#be123c",
|
|
397
|
-
9: "#9f1239",
|
|
398
|
-
10: "#881337",
|
|
399
|
-
11: "#4c0519",
|
|
400
|
-
12: "#2d030e"
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
var defaultTheme = {
|
|
404
|
-
colors: defaultColors,
|
|
405
|
-
// 1 unit = 4px
|
|
406
|
-
spacing: {
|
|
407
|
-
px: 1,
|
|
408
|
-
0: 0,
|
|
409
|
-
"0.5": 2,
|
|
410
|
-
1: 4,
|
|
411
|
-
"1.5": 6,
|
|
412
|
-
2: 8,
|
|
413
|
-
"2.5": 10,
|
|
414
|
-
3: 12,
|
|
415
|
-
"3.5": 14,
|
|
416
|
-
4: 16,
|
|
417
|
-
5: 20,
|
|
418
|
-
6: 24,
|
|
419
|
-
7: 28,
|
|
420
|
-
8: 32,
|
|
421
|
-
9: 36,
|
|
422
|
-
10: 40,
|
|
423
|
-
11: 44,
|
|
424
|
-
12: 48,
|
|
425
|
-
14: 56,
|
|
426
|
-
16: 64,
|
|
427
|
-
20: 80,
|
|
428
|
-
24: 96,
|
|
429
|
-
28: 112,
|
|
430
|
-
32: 128,
|
|
431
|
-
36: 144,
|
|
432
|
-
40: 160,
|
|
433
|
-
44: 176,
|
|
434
|
-
48: 192,
|
|
435
|
-
52: 208,
|
|
436
|
-
56: 224,
|
|
437
|
-
60: 240,
|
|
438
|
-
64: 256,
|
|
439
|
-
72: 288,
|
|
440
|
-
80: 320,
|
|
441
|
-
96: 384,
|
|
442
|
-
auto: "auto",
|
|
443
|
-
full: "100%",
|
|
444
|
-
"1/2": "50%",
|
|
445
|
-
"1/3": "33.333333%",
|
|
446
|
-
"2/3": "66.666667%",
|
|
447
|
-
"1/4": "25%",
|
|
448
|
-
"3/4": "75%",
|
|
449
|
-
// Dynamic viewport unit — see the comment on the 'screen' standalone utilities
|
|
450
|
-
// in utilities.ts for why dvh beats vh on mobile. Used by h-screen (w-screen
|
|
451
|
-
// has its own standalone entry so it never reaches this spacing lookup).
|
|
452
|
-
screen: "100dvh",
|
|
453
|
-
min: "min-content",
|
|
454
|
-
max: "max-content",
|
|
455
|
-
fit: "fit-content"
|
|
456
|
-
},
|
|
457
|
-
fontSize: {
|
|
458
|
-
xs: 12,
|
|
459
|
-
sm: 14,
|
|
460
|
-
base: 16,
|
|
461
|
-
lg: 18,
|
|
462
|
-
xl: 20,
|
|
463
|
-
"2xl": 24,
|
|
464
|
-
"3xl": 30,
|
|
465
|
-
"4xl": 36,
|
|
466
|
-
"5xl": 48,
|
|
467
|
-
"6xl": 60,
|
|
468
|
-
"7xl": 72,
|
|
469
|
-
"8xl": 96,
|
|
470
|
-
"9xl": 128
|
|
471
|
-
},
|
|
472
|
-
fontFamily: {
|
|
473
|
-
sans: "System",
|
|
474
|
-
mono: "Courier New",
|
|
475
|
-
serif: "Georgia"
|
|
476
|
-
},
|
|
477
|
-
fontWeight: {
|
|
478
|
-
thin: "100",
|
|
479
|
-
extralight: "200",
|
|
480
|
-
light: "300",
|
|
481
|
-
normal: "400",
|
|
482
|
-
medium: "500",
|
|
483
|
-
semibold: "600",
|
|
484
|
-
bold: "700",
|
|
485
|
-
extrabold: "800",
|
|
486
|
-
black: "900"
|
|
487
|
-
},
|
|
488
|
-
borderRadius: {
|
|
489
|
-
none: 0,
|
|
490
|
-
sm: 2,
|
|
491
|
-
DEFAULT: 4,
|
|
492
|
-
md: 6,
|
|
493
|
-
lg: 8,
|
|
494
|
-
xl: 12,
|
|
495
|
-
"2xl": 16,
|
|
496
|
-
"3xl": 24,
|
|
497
|
-
full: 9999
|
|
498
|
-
},
|
|
499
|
-
borderWidth: {
|
|
500
|
-
DEFAULT: 1,
|
|
501
|
-
0: 0,
|
|
502
|
-
2: 2,
|
|
503
|
-
4: 4,
|
|
504
|
-
8: 8
|
|
505
|
-
},
|
|
506
|
-
opacity: {
|
|
507
|
-
0: 0,
|
|
508
|
-
5: 0.05,
|
|
509
|
-
10: 0.1,
|
|
510
|
-
15: 0.15,
|
|
511
|
-
20: 0.2,
|
|
512
|
-
25: 0.25,
|
|
513
|
-
30: 0.3,
|
|
514
|
-
40: 0.4,
|
|
515
|
-
50: 0.5,
|
|
516
|
-
60: 0.6,
|
|
517
|
-
70: 0.7,
|
|
518
|
-
75: 0.75,
|
|
519
|
-
80: 0.8,
|
|
520
|
-
90: 0.9,
|
|
521
|
-
95: 0.95,
|
|
522
|
-
100: 1
|
|
523
|
-
},
|
|
524
|
-
lineHeight: {
|
|
525
|
-
none: 1,
|
|
526
|
-
tight: 1.25,
|
|
527
|
-
snug: 1.375,
|
|
528
|
-
normal: 1.5,
|
|
529
|
-
relaxed: 1.625,
|
|
530
|
-
loose: 2,
|
|
531
|
-
// Pixel values stored as strings; styleValueToCSS passes them through, toNativeValue strips the unit
|
|
532
|
-
3: "12px",
|
|
533
|
-
4: "16px",
|
|
534
|
-
5: "20px",
|
|
535
|
-
6: "24px",
|
|
536
|
-
7: "28px",
|
|
537
|
-
8: "32px",
|
|
538
|
-
9: "36px",
|
|
539
|
-
10: "40px"
|
|
540
|
-
},
|
|
541
|
-
letterSpacing: {
|
|
542
|
-
tighter: -0.8,
|
|
543
|
-
tight: -0.4,
|
|
544
|
-
normal: 0,
|
|
545
|
-
wide: 0.4,
|
|
546
|
-
wider: 0.8,
|
|
547
|
-
widest: 1.6
|
|
548
|
-
},
|
|
549
|
-
zIndex: {
|
|
550
|
-
auto: "auto",
|
|
551
|
-
0: 0,
|
|
552
|
-
10: 10,
|
|
553
|
-
20: 20,
|
|
554
|
-
30: 30,
|
|
555
|
-
40: 40,
|
|
556
|
-
50: 50
|
|
557
|
-
},
|
|
558
|
-
flex: {
|
|
559
|
-
1: 1,
|
|
560
|
-
auto: "auto",
|
|
561
|
-
// CSS: flex: auto = 1 1 auto; native: mapped to 1 in resolver
|
|
562
|
-
initial: "initial",
|
|
563
|
-
// CSS: flex: initial = 0 1 auto; native: mapped to 1
|
|
564
|
-
none: "none"
|
|
565
|
-
// CSS: flex: none = 0 0 auto; native: mapped to 0
|
|
566
|
-
},
|
|
567
|
-
shadow: {
|
|
568
|
-
sm: {
|
|
569
|
-
shadowColor: "#000",
|
|
570
|
-
shadowOffset: { width: 0, height: 1 },
|
|
571
|
-
shadowOpacity: 0.05,
|
|
572
|
-
shadowRadius: 2,
|
|
573
|
-
elevation: 1
|
|
574
|
-
},
|
|
575
|
-
DEFAULT: {
|
|
576
|
-
shadowColor: "#000",
|
|
577
|
-
shadowOffset: { width: 0, height: 2 },
|
|
578
|
-
shadowOpacity: 0.1,
|
|
579
|
-
shadowRadius: 4,
|
|
580
|
-
elevation: 2
|
|
581
|
-
},
|
|
582
|
-
md: {
|
|
583
|
-
shadowColor: "#000",
|
|
584
|
-
shadowOffset: { width: 0, height: 4 },
|
|
585
|
-
shadowOpacity: 0.1,
|
|
586
|
-
shadowRadius: 8,
|
|
587
|
-
elevation: 3
|
|
588
|
-
},
|
|
589
|
-
lg: {
|
|
590
|
-
shadowColor: "#000",
|
|
591
|
-
shadowOffset: { width: 0, height: 8 },
|
|
592
|
-
shadowOpacity: 0.1,
|
|
593
|
-
shadowRadius: 15,
|
|
594
|
-
elevation: 4
|
|
595
|
-
},
|
|
596
|
-
xl: {
|
|
597
|
-
shadowColor: "#000",
|
|
598
|
-
shadowOffset: { width: 0, height: 16 },
|
|
599
|
-
shadowOpacity: 0.1,
|
|
600
|
-
shadowRadius: 24,
|
|
601
|
-
elevation: 6
|
|
602
|
-
},
|
|
603
|
-
"2xl": {
|
|
604
|
-
shadowColor: "#000",
|
|
605
|
-
shadowOffset: { width: 0, height: 24 },
|
|
606
|
-
shadowOpacity: 0.25,
|
|
607
|
-
shadowRadius: 48,
|
|
608
|
-
elevation: 8
|
|
609
|
-
},
|
|
610
|
-
none: {
|
|
611
|
-
shadowColor: "transparent",
|
|
612
|
-
shadowOffset: { width: 0, height: 0 },
|
|
613
|
-
shadowOpacity: 0,
|
|
614
|
-
shadowRadius: 0,
|
|
615
|
-
elevation: 0
|
|
616
|
-
}
|
|
617
|
-
},
|
|
618
|
-
screens: {
|
|
619
|
-
sm: 576,
|
|
620
|
-
// small tablets / large phones (landscape)
|
|
621
|
-
md: 768,
|
|
622
|
-
// tablets (iPad and up)
|
|
623
|
-
lg: 1024,
|
|
624
|
-
// large tablets (iPad Pro)
|
|
625
|
-
xl: 1280,
|
|
626
|
-
// desktop
|
|
627
|
-
"2xl": 1536
|
|
628
|
-
},
|
|
629
|
-
// Empty by default — the 4 built-in presets (spin/ping/pulse/bounce) are handled
|
|
630
|
-
// directly in the `animate` resolver, not through this theme table. This exists so
|
|
631
|
-
// user-defined ones (kbach.config.js theme.extend.keyframes/animation) merge in
|
|
632
|
-
// alongside them without needing to redeclare the built-ins.
|
|
633
|
-
keyframes: {},
|
|
634
|
-
animation: {}
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
// src/core/reset.ts
|
|
638
|
-
var RESET_STYLE_ID = "kbach-reset";
|
|
639
|
-
var BASE_RESET = [
|
|
640
|
-
// border-style: solid means border-N utilities show a visible border without an extra border-solid class.
|
|
641
|
-
// border-width: 0 keeps all elements borderless by default.
|
|
642
|
-
"*, *::before, *::after { box-sizing: border-box; border-width: 0; border-style: solid; border-color: currentColor; }",
|
|
643
|
-
"body { margin: 0; padding: 0; }",
|
|
644
|
-
"h1, h2, h3, h4, h5, h6 { margin: 0; font-size: inherit; font-weight: inherit; }",
|
|
645
|
-
"p { margin: 0; }",
|
|
646
|
-
"a { color: inherit; text-decoration: none; }",
|
|
647
|
-
"ul, ol { margin: 0; padding: 0; list-style: none; }",
|
|
648
|
-
"img, video, svg { display: block; max-width: 100%; }",
|
|
649
|
-
// appearance: none is deliberately NOT applied to checkbox/radio/select below —
|
|
650
|
-
// stripping it hides their native checkmark/arrow with nothing rendered in its
|
|
651
|
-
// place, leaving an invisible checkbox or an arrow-less <select> that looks like
|
|
652
|
-
// plain text. Text-like inputs, textarea, and button don't have that problem
|
|
653
|
-
// (their native chrome is just a skin around content utilities can fully
|
|
654
|
-
// restyle), so they keep the blank-canvas treatment.
|
|
655
|
-
"input:not([type='checkbox']):not([type='radio']), textarea { appearance: none; -webkit-appearance: none; background: transparent; padding: 0; margin: 0; font: inherit; color: inherit; line-height: inherit; }",
|
|
656
|
-
// Native checkbox/radio/range still get typography + spacing normalized, and
|
|
657
|
-
// accent-color re-themes their native indicator to the current text color
|
|
658
|
-
// instead of the browser/OS default blue, so they stay on-brand without
|
|
659
|
-
// needing to be rebuilt from scratch.
|
|
660
|
-
"input[type='checkbox'], input[type='radio'], input[type='range'] { margin: 0; font: inherit; accent-color: currentColor; }",
|
|
661
|
-
// select keeps its native chrome (border/background/arrow are all part of the
|
|
662
|
-
// same OS-drawn widget that appearance: none would blank out) — only typography
|
|
663
|
-
// and spacing are normalized so it still matches surrounding text.
|
|
664
|
-
"select { margin: 0; font: inherit; color: inherit; line-height: inherit; }",
|
|
665
|
-
"button { appearance: none; -webkit-appearance: none; background: transparent; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; line-height: inherit; text-align: inherit; }",
|
|
666
|
-
"button, [role='button'] { cursor: pointer; }",
|
|
667
|
-
":disabled { cursor: default; }",
|
|
668
|
-
"textarea { resize: vertical; }",
|
|
669
|
-
// Firefox renders placeholders at ~54% opacity by default; every other browser uses 1 —
|
|
670
|
-
// normalize to 1 so placeholder color is consistent and fully controlled by the placeholder: modifier.
|
|
671
|
-
"::placeholder { opacity: 1; }",
|
|
672
|
-
"input[type='number']::-webkit-inner-spin-button, input[type='number']::-webkit-outer-spin-button { margin: 0; }",
|
|
673
|
-
"input[type='search']::-webkit-search-decoration, input[type='search']::-webkit-search-cancel-button { -webkit-appearance: none; }",
|
|
674
|
-
"fieldset { padding: 0; margin: 0; }",
|
|
675
|
-
"table { border-collapse: collapse; border-spacing: 0; }"
|
|
676
|
-
].join("\n");
|
|
677
|
-
|
|
678
|
-
// src/core/cache.ts
|
|
679
|
-
var LRUCache = class {
|
|
680
|
-
constructor(capacity = 1e4, onEvict) {
|
|
681
|
-
this.capacity = capacity;
|
|
682
|
-
if (capacity <= 0) throw new Error("LRUCache: capacity must be a positive integer");
|
|
683
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
684
|
-
this.onEvict = onEvict;
|
|
685
|
-
}
|
|
686
|
-
get(key) {
|
|
687
|
-
if (!this.cache.has(key)) return void 0;
|
|
688
|
-
const value = this.cache.get(key);
|
|
689
|
-
this.cache.delete(key);
|
|
690
|
-
this.cache.set(key, value);
|
|
691
|
-
return value;
|
|
692
|
-
}
|
|
693
|
-
set(key, value) {
|
|
694
|
-
if (this.cache.has(key)) {
|
|
695
|
-
this.cache.delete(key);
|
|
696
|
-
} else if (this.cache.size >= this.capacity) {
|
|
697
|
-
const oldestKey = this.cache.keys().next().value;
|
|
698
|
-
const oldestValue = this.cache.get(oldestKey);
|
|
699
|
-
this.cache.delete(oldestKey);
|
|
700
|
-
this.onEvict?.(oldestKey, oldestValue);
|
|
701
|
-
}
|
|
702
|
-
this.cache.set(key, value);
|
|
703
|
-
return this;
|
|
704
|
-
}
|
|
705
|
-
has(key) {
|
|
706
|
-
return this.cache.has(key);
|
|
707
|
-
}
|
|
708
|
-
delete(key) {
|
|
709
|
-
return this.cache.delete(key);
|
|
710
|
-
}
|
|
711
|
-
clear() {
|
|
712
|
-
this.cache.clear();
|
|
713
|
-
}
|
|
714
|
-
get size() {
|
|
715
|
-
return this.cache.size;
|
|
716
|
-
}
|
|
717
|
-
};
|
|
718
|
-
|
|
719
|
-
// src/core/platform.ts
|
|
720
|
-
var isWeb = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
721
|
-
var isNative = !isWeb && (typeof globalThis.HermesInternal !== "undefined" || typeof globalThis.__fbBatchedBridge !== "undefined" || typeof navigator !== "undefined" && navigator.product === "ReactNative" || typeof globalThis.__REACT_NATIVE__ !== "undefined");
|
|
722
|
-
var _resolveTargetOverride = null;
|
|
723
|
-
function setResolveTarget(target) {
|
|
724
|
-
_resolveTargetOverride = target;
|
|
725
|
-
}
|
|
726
|
-
function getEffectiveIsWeb() {
|
|
727
|
-
if (_resolveTargetOverride) return _resolveTargetOverride === "web";
|
|
728
|
-
return isWeb || !isNative;
|
|
729
|
-
}
|
|
730
|
-
function toNativeValue(raw) {
|
|
731
|
-
if (/^-?\d+(\.\d+)?px$/.test(raw)) return parseFloat(raw);
|
|
732
|
-
if (/^-?\d+(\.\d+)?rem$/.test(raw)) return parseFloat(raw) * 16;
|
|
733
|
-
if (/^-?\d+(\.\d+)?em$/.test(raw)) return parseFloat(raw) * 16;
|
|
734
|
-
if (/^-?\d+(\.\d+)?$/.test(raw)) return parseFloat(raw);
|
|
735
|
-
return raw;
|
|
736
|
-
}
|
|
737
|
-
function escapeCSSSelector(cls) {
|
|
738
|
-
return cls.replace(/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// src/core/devWarn.ts
|
|
742
|
-
function kbachWarn(message) {
|
|
743
|
-
console.warn(
|
|
744
|
-
"%c[kbach]%c " + message,
|
|
745
|
-
"color:#8b5cf6;font-weight:700",
|
|
746
|
-
"color:inherit;font-weight:400"
|
|
747
|
-
);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// src/core/registry.ts
|
|
751
|
-
var BUILTIN_MODIFIERS = {
|
|
752
|
-
// ── Mode ─────────────────────────────────────────────────────────────────
|
|
753
|
-
dark: { darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
|
|
754
|
-
"not-light": { darkScheme: "dark", jsBehavior: "mode", jsMatch: (d) => d },
|
|
755
|
-
light: { darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
|
|
756
|
-
"not-dark": { darkScheme: "light", jsBehavior: "mode", jsMatch: (d) => !d },
|
|
757
|
-
// ── Interactive — JS state + CSS pseudo ───────────────────────────────────
|
|
758
|
-
hover: { pseudo: ":hover", jsBehavior: "interactive", jsMatch: (_, s) => !!s.hover },
|
|
759
|
-
"not-hover": { pseudo: ":not(:hover)", jsBehavior: "interactive", jsMatch: (_, s) => !s.hover },
|
|
760
|
-
focus: { pseudo: ":focus", jsBehavior: "interactive", jsMatch: (_, s) => !!s.focus },
|
|
761
|
-
"not-focus": { pseudo: ":not(:focus)", jsBehavior: "interactive", jsMatch: (_, s) => !s.focus },
|
|
762
|
-
active: { pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.active || !!s.pressed },
|
|
763
|
-
"not-active": { pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.active && !s.pressed },
|
|
764
|
-
pressed: { pseudo: ":active", jsBehavior: "interactive", jsMatch: (_, s) => !!s.pressed || !!s.active },
|
|
765
|
-
"not-pressed": { pseudo: ":not(:active)", jsBehavior: "interactive", jsMatch: (_, s) => !s.pressed && !s.active },
|
|
766
|
-
disabled: { pseudo: ":disabled", jsBehavior: "interactive", jsMatch: (_, s) => !!s.disabled },
|
|
767
|
-
"not-disabled": { pseudo: ":not(:disabled)", jsBehavior: "interactive", jsMatch: (_, s) => !s.disabled },
|
|
768
|
-
checked: { pseudo: ":checked", jsBehavior: "interactive", jsMatch: (_, s) => !!s.checked },
|
|
769
|
-
"not-checked": { pseudo: ":not(:checked)", jsBehavior: "interactive", jsMatch: (_, s) => !s.checked },
|
|
770
|
-
visited: { pseudo: ":visited", jsBehavior: "interactive", jsMatch: (_, s) => !!s.visited },
|
|
771
|
-
"not-visited": { pseudo: ":not(:visited)", jsBehavior: "interactive", jsMatch: (_, s) => !s.visited },
|
|
772
|
-
placeholder: { pseudo: "::placeholder", jsBehavior: "interactive", jsMatch: (_, s) => !!s.placeholder },
|
|
773
|
-
// ── CSS-only pseudo-classes (structural) ──────────────────────────────────
|
|
774
|
-
first: { pseudo: ":first-child", jsBehavior: "css-only", forcesImportant: true },
|
|
775
|
-
last: { pseudo: ":last-child", jsBehavior: "css-only", forcesImportant: true },
|
|
776
|
-
odd: { pseudo: ":nth-child(odd)", jsBehavior: "css-only", forcesImportant: true },
|
|
777
|
-
even: { pseudo: ":nth-child(even)", jsBehavior: "css-only", forcesImportant: true },
|
|
778
|
-
only: { pseudo: ":only-child", jsBehavior: "css-only", forcesImportant: true },
|
|
779
|
-
"focus-within": { pseudo: ":focus-within", jsBehavior: "css-only", forcesImportant: true },
|
|
780
|
-
"focus-visible": { pseudo: ":focus-visible", jsBehavior: "css-only", forcesImportant: true },
|
|
781
|
-
// ── CSS-only pseudo-elements ───────────────────────────────────────────────
|
|
782
|
-
before: { pseudo: "::before", jsBehavior: "css-only" },
|
|
783
|
-
after: { pseudo: "::after", jsBehavior: "css-only" },
|
|
784
|
-
selection: { pseudo: "::selection", jsBehavior: "css-only" },
|
|
785
|
-
"first-letter": { pseudo: "::first-letter", jsBehavior: "css-only" },
|
|
786
|
-
"first-line": { pseudo: "::first-line", jsBehavior: "css-only" },
|
|
787
|
-
marker: { pseudo: "::marker", jsBehavior: "css-only" },
|
|
788
|
-
// ── Group / peer ancestor selectors (CSS-only) ─────────────────────────────
|
|
789
|
-
"group-hover": { ancestorSelector: ".group:hover ", jsBehavior: "css-only", forcesImportant: true },
|
|
790
|
-
"group-focus": { ancestorSelector: ".group:focus ", jsBehavior: "css-only", forcesImportant: true },
|
|
791
|
-
"peer-hover": { ancestorSelector: ".peer:hover ~ ", jsBehavior: "css-only", forcesImportant: true },
|
|
792
|
-
"peer-focus": { ancestorSelector: ".peer:focus ~ ", jsBehavior: "css-only", forcesImportant: true },
|
|
793
|
-
// ── Responsive — both CSS (@media min-width) and JS (breakpoints set) ──────
|
|
794
|
-
sm: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("sm") },
|
|
795
|
-
md: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("md") },
|
|
796
|
-
lg: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("lg") },
|
|
797
|
-
xl: { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("xl") },
|
|
798
|
-
"2xl": { isResponsive: true, jsBehavior: "responsive", jsMatch: (_, __, bp) => bp.has("2xl") },
|
|
799
|
-
// ── Print media (CSS-only) ─────────────────────────────────────────────────
|
|
800
|
-
print: { mediaQuery: "print", jsBehavior: "css-only", forcesImportant: true },
|
|
801
|
-
// ── Orientation / accessibility media (CSS-only) ───────────────────────────
|
|
802
|
-
landscape: { mediaQuery: "(orientation: landscape)", jsBehavior: "css-only", forcesImportant: true },
|
|
803
|
-
portrait: { mediaQuery: "(orientation: portrait)", jsBehavior: "css-only", forcesImportant: true },
|
|
804
|
-
"motion-reduce": { mediaQuery: "(prefers-reduced-motion: reduce)", jsBehavior: "css-only", forcesImportant: true },
|
|
805
|
-
"motion-safe": { mediaQuery: "(prefers-reduced-motion: no-preference)", jsBehavior: "css-only", forcesImportant: true },
|
|
806
|
-
"contrast-more": { mediaQuery: "(prefers-contrast: more)", jsBehavior: "css-only", forcesImportant: true },
|
|
807
|
-
"contrast-less": { mediaQuery: "(prefers-contrast: less)", jsBehavior: "css-only", forcesImportant: true },
|
|
808
|
-
// ── Directionality (CSS-only) ──────────────────────────────────────────────
|
|
809
|
-
rtl: { dirSelector: '[dir="rtl"] ', jsBehavior: "css-only", forcesImportant: true },
|
|
810
|
-
ltr: { dirSelector: '[dir="ltr"] ', jsBehavior: "css-only", forcesImportant: true }
|
|
811
|
-
};
|
|
812
|
-
var _pluginModifiers = {};
|
|
813
|
-
var _allNames = null;
|
|
814
|
-
var _interactiveNames = null;
|
|
815
|
-
var _modeNames = null;
|
|
816
|
-
var _responsiveNames = null;
|
|
817
|
-
function _invalidate() {
|
|
818
|
-
_allNames = null;
|
|
819
|
-
_interactiveNames = null;
|
|
820
|
-
_modeNames = null;
|
|
821
|
-
_responsiveNames = null;
|
|
822
|
-
}
|
|
823
|
-
function registerModifier(name, def) {
|
|
824
|
-
if (process.env.NODE_ENV !== "production" && name in BUILTIN_MODIFIERS) {
|
|
825
|
-
kbachWarn(`"${name}" is built-in \u2014 pick another modifier name`);
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
_pluginModifiers[name] = def;
|
|
829
|
-
_invalidate();
|
|
830
|
-
}
|
|
831
|
-
function clearPluginModifiers() {
|
|
832
|
-
for (const k of Object.keys(_pluginModifiers)) delete _pluginModifiers[k];
|
|
833
|
-
_invalidate();
|
|
834
|
-
}
|
|
835
|
-
var NAMED_GROUP_PEER_RE = /^(group|peer)-(hover|focus)\/(.+)$/;
|
|
836
|
-
var _namedModifierCache = /* @__PURE__ */ new Map();
|
|
837
|
-
function getNamedGroupPeerModifier(name) {
|
|
838
|
-
const cached = _namedModifierCache.get(name);
|
|
839
|
-
if (cached) return cached;
|
|
840
|
-
const m = NAMED_GROUP_PEER_RE.exec(name);
|
|
841
|
-
if (!m) return void 0;
|
|
842
|
-
const [, kind, trigger, groupName] = m;
|
|
843
|
-
const escapedName = escapeCSSSelector(groupName);
|
|
844
|
-
const pseudo = trigger === "hover" ? ":hover" : ":focus";
|
|
845
|
-
const combinator = kind === "group" ? " " : " ~ ";
|
|
846
|
-
const def = {
|
|
847
|
-
ancestorSelector: `.${kind}\\/${escapedName}${pseudo}${combinator}`,
|
|
848
|
-
jsBehavior: "css-only",
|
|
849
|
-
forcesImportant: true
|
|
850
|
-
};
|
|
851
|
-
_namedModifierCache.set(name, def);
|
|
852
|
-
return def;
|
|
853
|
-
}
|
|
854
|
-
function getModifier(name) {
|
|
855
|
-
return BUILTIN_MODIFIERS[name] ?? _pluginModifiers[name] ?? getNamedGroupPeerModifier(name);
|
|
856
|
-
}
|
|
857
|
-
function isKnownModifier(name) {
|
|
858
|
-
return name in BUILTIN_MODIFIERS || name in _pluginModifiers || NAMED_GROUP_PEER_RE.test(name);
|
|
859
|
-
}
|
|
860
|
-
function _allEntries() {
|
|
861
|
-
return [...Object.entries(BUILTIN_MODIFIERS), ...Object.entries(_pluginModifiers)];
|
|
862
|
-
}
|
|
863
|
-
function getInteractiveModifiers() {
|
|
864
|
-
if (!_interactiveNames) {
|
|
865
|
-
_interactiveNames = new Set(_allEntries().filter(([, d]) => d.jsBehavior === "interactive").map(([k]) => k));
|
|
866
|
-
}
|
|
867
|
-
return _interactiveNames;
|
|
868
|
-
}
|
|
869
|
-
function getResponsiveModifiers() {
|
|
870
|
-
if (!_responsiveNames) {
|
|
871
|
-
_responsiveNames = new Set(_allEntries().filter(([, d]) => d.jsBehavior === "responsive").map(([k]) => k));
|
|
872
|
-
}
|
|
873
|
-
return _responsiveNames;
|
|
874
|
-
}
|
|
875
|
-
function matchModifier(name, isDark, state, breakpoints) {
|
|
876
|
-
return getModifier(name)?.jsMatch?.(isDark, state, breakpoints) ?? false;
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
// src/core/utilities.ts
|
|
880
|
-
function resolveColor(value, colors, isArbitrary) {
|
|
881
|
-
if (isArbitrary) return value;
|
|
882
|
-
const slashIdx = value.indexOf("/");
|
|
883
|
-
const colorPart = slashIdx > 0 ? value.slice(0, slashIdx) : value;
|
|
884
|
-
const opacityPart = slashIdx > 0 ? value.slice(slashIdx + 1) : null;
|
|
885
|
-
let hex = null;
|
|
886
|
-
if (colorPart in colors) {
|
|
887
|
-
const entry = colors[colorPart];
|
|
888
|
-
if (typeof entry === "string") hex = entry;
|
|
889
|
-
else if (typeof entry === "object" && "6" in entry) hex = entry["6"];
|
|
890
|
-
} else {
|
|
891
|
-
const lastDash = colorPart.lastIndexOf("-");
|
|
892
|
-
if (lastDash > 0) {
|
|
893
|
-
const colorName = colorPart.slice(0, lastDash);
|
|
894
|
-
const shade = colorPart.slice(lastDash + 1);
|
|
895
|
-
const scale = colors[colorName];
|
|
896
|
-
if (scale && typeof scale === "object" && shade in scale) {
|
|
897
|
-
hex = scale[shade] ?? null;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
if (!hex) return null;
|
|
902
|
-
if (!opacityPart) {
|
|
903
|
-
if (!getEffectiveIsWeb() && hex.startsWith("#") && hex.length === 9) {
|
|
904
|
-
return hexToRgba(hex, Math.round(parseInt(hex.slice(7, 9), 16) / 255 * 1e3) / 1e3);
|
|
905
|
-
}
|
|
906
|
-
return hex;
|
|
907
|
-
}
|
|
908
|
-
let alpha;
|
|
909
|
-
if (opacityPart.startsWith("[") && opacityPart.endsWith("]")) {
|
|
910
|
-
const v = parseFloat(opacityPart.slice(1, -1));
|
|
911
|
-
alpha = v > 1 ? v / 100 : v;
|
|
912
|
-
} else {
|
|
913
|
-
alpha = parseFloat(opacityPart) / 100;
|
|
914
|
-
}
|
|
915
|
-
if (isNaN(alpha)) return hex;
|
|
916
|
-
if (alpha < 0) alpha = 0;
|
|
917
|
-
else if (alpha > 1) alpha = 1;
|
|
918
|
-
return hexToRgba(hex, alpha);
|
|
919
|
-
}
|
|
920
|
-
function parseHexRgb(hex) {
|
|
921
|
-
const h = hex.replace("#", "");
|
|
922
|
-
if (h.length === 3 || h.length === 4) {
|
|
923
|
-
return [
|
|
924
|
-
parseInt(h[0] + h[0], 16),
|
|
925
|
-
parseInt(h[1] + h[1], 16),
|
|
926
|
-
parseInt(h[2] + h[2], 16)
|
|
927
|
-
];
|
|
928
|
-
}
|
|
929
|
-
if (h.length === 6 || h.length === 8) {
|
|
930
|
-
return [
|
|
931
|
-
parseInt(h.slice(0, 2), 16),
|
|
932
|
-
parseInt(h.slice(2, 4), 16),
|
|
933
|
-
parseInt(h.slice(4, 6), 16)
|
|
934
|
-
];
|
|
935
|
-
}
|
|
936
|
-
return null;
|
|
937
|
-
}
|
|
938
|
-
function hexToRgba(hex, alpha) {
|
|
939
|
-
const rgb = parseHexRgb(hex);
|
|
940
|
-
if (!rgb) return hex;
|
|
941
|
-
const [r, g, b] = rgb;
|
|
942
|
-
return `rgba(${r},${g},${b},${alpha})`;
|
|
943
|
-
}
|
|
944
|
-
function withOpacityVar(color, varName) {
|
|
945
|
-
if (!color.startsWith("#")) return color;
|
|
946
|
-
const rgb = parseHexRgb(color);
|
|
947
|
-
if (!rgb) return color;
|
|
948
|
-
const [r, g, b] = rgb;
|
|
949
|
-
return `rgba(${r},${g},${b},var(${varName},1))`;
|
|
950
|
-
}
|
|
951
|
-
function resolveSpacing(value, negative, spacing, isArbitrary) {
|
|
952
|
-
if (isArbitrary) {
|
|
953
|
-
const resolved = getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
954
|
-
if (negative) {
|
|
955
|
-
if (typeof resolved === "number") return -resolved;
|
|
956
|
-
if (typeof resolved === "string") {
|
|
957
|
-
if (/^\d/.test(resolved)) return `-${resolved}`;
|
|
958
|
-
if (/^(calc|var|min|max|clamp|env)\s*\(/.test(resolved)) return `calc(-1 * (${resolved}))`;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
return resolved;
|
|
962
|
-
}
|
|
963
|
-
const raw = spacing[value];
|
|
964
|
-
if (raw === void 0) return null;
|
|
965
|
-
if (typeof raw === "number") return negative ? -raw : raw;
|
|
966
|
-
if (raw === "auto") return "auto";
|
|
967
|
-
if (negative && typeof raw === "string" && raw.endsWith("%")) {
|
|
968
|
-
return `-${raw}`;
|
|
969
|
-
}
|
|
970
|
-
return raw;
|
|
971
|
-
}
|
|
972
|
-
function resolveSizing(value, spacing, isArbitrary) {
|
|
973
|
-
if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
974
|
-
const raw = spacing[value];
|
|
975
|
-
if (raw !== void 0) return raw;
|
|
976
|
-
if (/^\d+\/\d+$/.test(value)) {
|
|
977
|
-
const [num, den] = value.split("/").map(Number);
|
|
978
|
-
if (!den) return null;
|
|
979
|
-
return `${(num / den * 100).toFixed(6)}%`;
|
|
980
|
-
}
|
|
981
|
-
return null;
|
|
982
|
-
}
|
|
983
|
-
function resolveRadius(value, radii, isArbitrary) {
|
|
984
|
-
if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
985
|
-
const key = value === "" ? "DEFAULT" : value;
|
|
986
|
-
return radii[key] ?? null;
|
|
987
|
-
}
|
|
988
|
-
function resolveFontSize(value, fontSizes, isArbitrary) {
|
|
989
|
-
if (isArbitrary) return getEffectiveIsWeb() ? value : toNativeValue(value);
|
|
990
|
-
return fontSizes[value] ?? null;
|
|
991
|
-
}
|
|
992
|
-
var FILTER_COMPOSE = "var(--kb-blur,) var(--kb-brightness,) var(--kb-contrast,) var(--kb-grayscale,) var(--kb-hue-rotate,) var(--kb-invert,) var(--kb-saturate,) var(--kb-sepia,) var(--kb-drop-shadow,)";
|
|
993
|
-
var BACKDROP_FILTER_COMPOSE = "var(--kb-backdrop-blur,) var(--kb-backdrop-brightness,) var(--kb-backdrop-contrast,) var(--kb-backdrop-grayscale,) var(--kb-backdrop-hue-rotate,) var(--kb-backdrop-invert,) var(--kb-backdrop-opacity,) var(--kb-backdrop-saturate,) var(--kb-backdrop-sepia,)";
|
|
994
|
-
var _standalone = null;
|
|
995
|
-
function buildStandalone() {
|
|
996
|
-
const web = getEffectiveIsWeb();
|
|
997
|
-
return {
|
|
998
|
-
// Display
|
|
999
|
-
// React Native only supports display:'flex'|'none'. Setting 'flex' explicitly is
|
|
1000
|
-
// a no-op normally, but is needed to re-show an element that was hidden via `hidden`.
|
|
1001
|
-
// `grid`, `contents`, `flow-root` have no native equivalent and stay null there.
|
|
1002
|
-
// The inline-* family (inline, inline-block, inline-flex, inline-grid) falls back
|
|
1003
|
-
// to 'flex' on native instead — like plain `flex`, this is a no-op most of the
|
|
1004
|
-
// time, but without it these utilities couldn't re-show a `hidden` element on
|
|
1005
|
-
// native either (null → no style applied → still display:'none').
|
|
1006
|
-
flex: { display: "flex" },
|
|
1007
|
-
block: web ? { display: "block" } : null,
|
|
1008
|
-
"inline-block": { display: web ? "inline-block" : "flex" },
|
|
1009
|
-
inline: { display: web ? "inline" : "flex" },
|
|
1010
|
-
grid: web ? { display: "grid" } : null,
|
|
1011
|
-
grd: web ? { display: "grid" } : null,
|
|
1012
|
-
"inline-flex": { display: web ? "inline-flex" : "flex" },
|
|
1013
|
-
"inline-grid": { display: web ? "inline-grid" : "flex" },
|
|
1014
|
-
hidden: { display: "none" },
|
|
1015
|
-
contents: web ? { display: "contents" } : null,
|
|
1016
|
-
"flow-root": web ? { display: "flow-root" } : null,
|
|
1017
|
-
// Flex direction (both web and native)
|
|
1018
|
-
"flex-row": { flexDirection: "row" },
|
|
1019
|
-
"flex-col": { flexDirection: "column" },
|
|
1020
|
-
"flex-row-reverse": { flexDirection: "row-reverse" },
|
|
1021
|
-
"flex-col-reverse": { flexDirection: "column-reverse" },
|
|
1022
|
-
// Flex wrap (both)
|
|
1023
|
-
"flex-wrap": { flexWrap: "wrap" },
|
|
1024
|
-
"flex-wrap-reverse": { flexWrap: "wrap-reverse" },
|
|
1025
|
-
"flex-nowrap": { flexWrap: "nowrap" },
|
|
1026
|
-
// Flex grow / shrink (both)
|
|
1027
|
-
"flex-grow": { flexGrow: 1 },
|
|
1028
|
-
"flex-grow-0": { flexGrow: 0 },
|
|
1029
|
-
"flex-shrink": { flexShrink: 1 },
|
|
1030
|
-
"flex-shrink-0": { flexShrink: 0 },
|
|
1031
|
-
// Align items (both)
|
|
1032
|
-
"items-start": { alignItems: "flex-start" },
|
|
1033
|
-
"items-end": { alignItems: "flex-end" },
|
|
1034
|
-
"items-center": { alignItems: "center" },
|
|
1035
|
-
"items-baseline": { alignItems: "baseline" },
|
|
1036
|
-
"items-stretch": { alignItems: "stretch" },
|
|
1037
|
-
// Justify content (both)
|
|
1038
|
-
"justify-start": { justifyContent: "flex-start" },
|
|
1039
|
-
"justify-end": { justifyContent: "flex-end" },
|
|
1040
|
-
"justify-center": { justifyContent: "center" },
|
|
1041
|
-
"justify-between": { justifyContent: "space-between" },
|
|
1042
|
-
"justify-around": { justifyContent: "space-around" },
|
|
1043
|
-
"justify-evenly": { justifyContent: "space-evenly" },
|
|
1044
|
-
// Align content (both)
|
|
1045
|
-
"content-start": { alignContent: "flex-start" },
|
|
1046
|
-
"content-end": { alignContent: "flex-end" },
|
|
1047
|
-
"content-center": { alignContent: "center" },
|
|
1048
|
-
"content-between": { alignContent: "space-between" },
|
|
1049
|
-
"content-around": { alignContent: "space-around" },
|
|
1050
|
-
"content-evenly": { alignContent: "space-evenly" },
|
|
1051
|
-
"content-stretch": { alignContent: "stretch" },
|
|
1052
|
-
// Align self (both)
|
|
1053
|
-
"self-auto": { alignSelf: "auto" },
|
|
1054
|
-
"self-start": { alignSelf: "flex-start" },
|
|
1055
|
-
"self-end": { alignSelf: "flex-end" },
|
|
1056
|
-
"self-center": { alignSelf: "center" },
|
|
1057
|
-
"self-stretch": { alignSelf: "stretch" },
|
|
1058
|
-
"self-baseline": { alignSelf: "baseline" },
|
|
1059
|
-
// Text align (both)
|
|
1060
|
-
"text-left": { textAlign: "left" },
|
|
1061
|
-
"text-right": { textAlign: "right" },
|
|
1062
|
-
"text-center": { textAlign: "center" },
|
|
1063
|
-
"text-justify": { textAlign: "justify" },
|
|
1064
|
-
// Font weight shortcuts (both)
|
|
1065
|
-
"font-thin": { fontWeight: "100" },
|
|
1066
|
-
"font-extralight": { fontWeight: "200" },
|
|
1067
|
-
"font-light": { fontWeight: "300" },
|
|
1068
|
-
"font-normal": { fontWeight: "400" },
|
|
1069
|
-
"font-medium": { fontWeight: "500" },
|
|
1070
|
-
"font-semibold": { fontWeight: "600" },
|
|
1071
|
-
"font-bold": { fontWeight: "700" },
|
|
1072
|
-
"font-extrabold": { fontWeight: "800" },
|
|
1073
|
-
"font-black": { fontWeight: "900" },
|
|
1074
|
-
// Text decoration (overline is web-only)
|
|
1075
|
-
underline: { textDecorationLine: "underline" },
|
|
1076
|
-
overline: web ? { textDecorationLine: "overline" } : null,
|
|
1077
|
-
"line-through": { textDecorationLine: "line-through" },
|
|
1078
|
-
"no-underline": { textDecorationLine: "none" },
|
|
1079
|
-
// Text transform (both)
|
|
1080
|
-
uppercase: { textTransform: "uppercase" },
|
|
1081
|
-
lowercase: { textTransform: "lowercase" },
|
|
1082
|
-
capitalize: { textTransform: "capitalize" },
|
|
1083
|
-
"normal-case": { textTransform: "none" },
|
|
1084
|
-
// Font style (both)
|
|
1085
|
-
italic: { fontStyle: "italic" },
|
|
1086
|
-
"non-italic": { fontStyle: "normal" },
|
|
1087
|
-
// Position (fixed/sticky/static are web-only; RN only supports relative/absolute)
|
|
1088
|
-
relative: { position: "relative" },
|
|
1089
|
-
absolute: { position: "absolute" },
|
|
1090
|
-
fixed: web ? { position: "fixed" } : null,
|
|
1091
|
-
sticky: web ? { position: "sticky" } : null,
|
|
1092
|
-
static: web ? { position: "static" } : null,
|
|
1093
|
-
// Visibility (no `visibility` prop on native; use opacity instead)
|
|
1094
|
-
visible: web ? { visibility: "visible" } : null,
|
|
1095
|
-
invisible: web ? { visibility: "hidden" } : { opacity: 0 },
|
|
1096
|
-
// Overflow (RN supports 'hidden' | 'visible' | 'scroll'; not 'auto')
|
|
1097
|
-
"overflow-hidden": { overflow: "hidden" },
|
|
1098
|
-
"overflow-visible": { overflow: "visible" },
|
|
1099
|
-
"overflow-scroll": { overflow: "scroll" },
|
|
1100
|
-
"overflow-auto": web ? { overflow: "auto" } : { overflow: "scroll" },
|
|
1101
|
-
// overflowX / overflowY are web-only
|
|
1102
|
-
"overflow-x-hidden": web ? { overflowX: "hidden" } : null,
|
|
1103
|
-
"overflow-x-scroll": web ? { overflowX: "scroll" } : null,
|
|
1104
|
-
"overflow-x-auto": web ? { overflowX: "auto" } : null,
|
|
1105
|
-
"overflow-y-hidden": web ? { overflowY: "hidden" } : null,
|
|
1106
|
-
"overflow-y-scroll": web ? { overflowY: "scroll" } : null,
|
|
1107
|
-
"overflow-y-auto": web ? { overflowY: "auto" } : null,
|
|
1108
|
-
// Object fit (web-only; use resizeMode prop on RN Image)
|
|
1109
|
-
"object-contain": web ? { objectFit: "contain" } : null,
|
|
1110
|
-
"object-cover": web ? { objectFit: "cover" } : null,
|
|
1111
|
-
"object-fill": web ? { objectFit: "fill" } : null,
|
|
1112
|
-
"object-none": web ? { objectFit: "none" } : null,
|
|
1113
|
-
"object-scale-down": web ? { objectFit: "scale-down" } : null,
|
|
1114
|
-
// Border style (both)
|
|
1115
|
-
"border-solid": { borderStyle: "solid" },
|
|
1116
|
-
"border-dashed": { borderStyle: "dashed" },
|
|
1117
|
-
"border-dotted": { borderStyle: "dotted" },
|
|
1118
|
-
"border-none": { borderWidth: 0 },
|
|
1119
|
-
// Border sides default width (both)
|
|
1120
|
-
"border-t": { borderTopWidth: 1 },
|
|
1121
|
-
"border-r": { borderRightWidth: 1 },
|
|
1122
|
-
"border-b": { borderBottomWidth: 1 },
|
|
1123
|
-
"border-l": { borderLeftWidth: 1 },
|
|
1124
|
-
// Cursor (web-only)
|
|
1125
|
-
"cursor-auto": web ? { cursor: "auto" } : null,
|
|
1126
|
-
"cursor-default": web ? { cursor: "default" } : null,
|
|
1127
|
-
"cursor-pointer": web ? { cursor: "pointer" } : null,
|
|
1128
|
-
"cursor-wait": web ? { cursor: "wait" } : null,
|
|
1129
|
-
"cursor-text": web ? { cursor: "text" } : null,
|
|
1130
|
-
"cursor-move": web ? { cursor: "move" } : null,
|
|
1131
|
-
"cursor-not-allowed": web ? { cursor: "not-allowed" } : null,
|
|
1132
|
-
// User select (web-only)
|
|
1133
|
-
"select-none": web ? { userSelect: "none" } : null,
|
|
1134
|
-
"select-text": web ? { userSelect: "text" } : null,
|
|
1135
|
-
"select-all": web ? { userSelect: "all" } : null,
|
|
1136
|
-
"select-auto": web ? { userSelect: "auto" } : null,
|
|
1137
|
-
// Pointer events (both)
|
|
1138
|
-
"pointer-events-none": { pointerEvents: "none" },
|
|
1139
|
-
"pointer-events-auto": { pointerEvents: "auto" },
|
|
1140
|
-
// Whitespace (web-only; RN Text uses numberOfLines prop instead)
|
|
1141
|
-
"whitespace-normal": web ? { whiteSpace: "normal" } : null,
|
|
1142
|
-
"whitespace-nowrap": web ? { whiteSpace: "nowrap" } : null,
|
|
1143
|
-
"whitespace-pre": web ? { whiteSpace: "pre" } : null,
|
|
1144
|
-
"whitespace-pre-wrap": web ? { whiteSpace: "pre-wrap" } : null,
|
|
1145
|
-
"whitespace-pre-line": web ? { whiteSpace: "pre-line" } : null,
|
|
1146
|
-
// Word break (web-only)
|
|
1147
|
-
"break-normal": web ? { overflowWrap: "normal", wordBreak: "normal" } : null,
|
|
1148
|
-
"break-words": web ? { overflowWrap: "break-word" } : null,
|
|
1149
|
-
"break-all": web ? { wordBreak: "break-all" } : null,
|
|
1150
|
-
// Misc web-only
|
|
1151
|
-
truncate: web ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } : null,
|
|
1152
|
-
"box-border": web ? { boxSizing: "border-box" } : null,
|
|
1153
|
-
"box-content": web ? { boxSizing: "content-box" } : null,
|
|
1154
|
-
"appearance-none": web ? { appearance: "none" } : null,
|
|
1155
|
-
"outline-none": web ? { outline: "none", outlineOffset: "0" } : null,
|
|
1156
|
-
outline: web ? { outline: "2px solid transparent", outlineOffset: "2px" } : null,
|
|
1157
|
-
resize: web ? { resize: "both" } : null,
|
|
1158
|
-
"resize-none": web ? { resize: "none" } : null,
|
|
1159
|
-
"resize-y": web ? { resize: "vertical" } : null,
|
|
1160
|
-
"resize-x": web ? { resize: "horizontal" } : null,
|
|
1161
|
-
antialiased: web ? { WebkitFontSmoothing: "antialiased", MozOsxFontSmoothing: "grayscale" } : null,
|
|
1162
|
-
"subpixel-antialiased": web ? { WebkitFontSmoothing: "subpixel-antialiased", MozOsxFontSmoothing: "auto" } : null,
|
|
1163
|
-
"overflow-ellipsis": web ? { textOverflow: "ellipsis" } : null,
|
|
1164
|
-
"sr-only": web ? {
|
|
1165
|
-
position: "absolute",
|
|
1166
|
-
width: 1,
|
|
1167
|
-
height: 1,
|
|
1168
|
-
padding: 0,
|
|
1169
|
-
margin: -1,
|
|
1170
|
-
overflow: "hidden",
|
|
1171
|
-
clip: "rect(0,0,0,0)",
|
|
1172
|
-
whiteSpace: "nowrap",
|
|
1173
|
-
border: 0
|
|
1174
|
-
} : null,
|
|
1175
|
-
"not-sr-only": web ? {
|
|
1176
|
-
position: "static",
|
|
1177
|
-
width: "auto",
|
|
1178
|
-
height: "auto",
|
|
1179
|
-
padding: 0,
|
|
1180
|
-
margin: 0,
|
|
1181
|
-
overflow: "visible",
|
|
1182
|
-
clip: "auto",
|
|
1183
|
-
whiteSpace: "normal"
|
|
1184
|
-
} : null,
|
|
1185
|
-
// Lists (web-only)
|
|
1186
|
-
"list-none": web ? { listStyleType: "none" } : null,
|
|
1187
|
-
"list-disc": web ? { listStyleType: "disc" } : null,
|
|
1188
|
-
"list-decimal": web ? { listStyleType: "decimal" } : null,
|
|
1189
|
-
// Background clip (web-only)
|
|
1190
|
-
"bg-clip-border": web ? { backgroundClip: "border-box" } : null,
|
|
1191
|
-
"bg-clip-padding": web ? { backgroundClip: "padding-box" } : null,
|
|
1192
|
-
"bg-clip-content": web ? { backgroundClip: "content-box" } : null,
|
|
1193
|
-
"bg-clip-text": web ? { backgroundClip: "text", WebkitBackgroundClip: "text" } : null,
|
|
1194
|
-
// Background image
|
|
1195
|
-
"bg-none": web ? { backgroundImage: "none" } : null,
|
|
1196
|
-
// Background size (web-only)
|
|
1197
|
-
"bg-auto": web ? { backgroundSize: "auto" } : null,
|
|
1198
|
-
"bg-cover": web ? { backgroundSize: "cover" } : null,
|
|
1199
|
-
"bg-contain": web ? { backgroundSize: "contain" } : null,
|
|
1200
|
-
// Background position (web-only)
|
|
1201
|
-
"bg-center": web ? { backgroundPosition: "center" } : null,
|
|
1202
|
-
"bg-top": web ? { backgroundPosition: "top" } : null,
|
|
1203
|
-
"bg-bottom": web ? { backgroundPosition: "bottom" } : null,
|
|
1204
|
-
"bg-left": web ? { backgroundPosition: "left" } : null,
|
|
1205
|
-
"bg-right": web ? { backgroundPosition: "right" } : null,
|
|
1206
|
-
"bg-left-top": web ? { backgroundPosition: "left top" } : null,
|
|
1207
|
-
"bg-left-bottom": web ? { backgroundPosition: "left bottom" } : null,
|
|
1208
|
-
"bg-right-top": web ? { backgroundPosition: "right top" } : null,
|
|
1209
|
-
"bg-right-bottom": web ? { backgroundPosition: "right bottom" } : null,
|
|
1210
|
-
// Background repeat (web-only)
|
|
1211
|
-
"bg-repeat": web ? { backgroundRepeat: "repeat" } : null,
|
|
1212
|
-
"bg-no-repeat": web ? { backgroundRepeat: "no-repeat" } : null,
|
|
1213
|
-
"bg-repeat-x": web ? { backgroundRepeat: "repeat-x" } : null,
|
|
1214
|
-
"bg-repeat-y": web ? { backgroundRepeat: "repeat-y" } : null,
|
|
1215
|
-
"bg-repeat-round": web ? { backgroundRepeat: "round" } : null,
|
|
1216
|
-
"bg-repeat-space": web ? { backgroundRepeat: "space" } : null,
|
|
1217
|
-
// Background attachment (web-only)
|
|
1218
|
-
"bg-fixed": web ? { backgroundAttachment: "fixed" } : null,
|
|
1219
|
-
"bg-local": web ? { backgroundAttachment: "local" } : null,
|
|
1220
|
-
"bg-scroll": web ? { backgroundAttachment: "scroll" } : null,
|
|
1221
|
-
// Object position (web-only)
|
|
1222
|
-
"object-center": web ? { objectPosition: "center" } : null,
|
|
1223
|
-
"object-top": web ? { objectPosition: "top" } : null,
|
|
1224
|
-
"object-bottom": web ? { objectPosition: "bottom" } : null,
|
|
1225
|
-
"object-left": web ? { objectPosition: "left" } : null,
|
|
1226
|
-
"object-right": web ? { objectPosition: "right" } : null,
|
|
1227
|
-
"object-left-top": web ? { objectPosition: "left top" } : null,
|
|
1228
|
-
"object-left-bottom": web ? { objectPosition: "left bottom" } : null,
|
|
1229
|
-
"object-right-top": web ? { objectPosition: "right top" } : null,
|
|
1230
|
-
"object-right-bottom": web ? { objectPosition: "right bottom" } : null,
|
|
1231
|
-
// Table (web-only)
|
|
1232
|
-
table: web ? { display: "table" } : null,
|
|
1233
|
-
"table-auto": web ? { tableLayout: "auto" } : null,
|
|
1234
|
-
"table-fixed": web ? { tableLayout: "fixed" } : null,
|
|
1235
|
-
"caption-top": web ? { captionSide: "top" } : null,
|
|
1236
|
-
"caption-bottom": web ? { captionSide: "bottom" } : null,
|
|
1237
|
-
"border-collapse": web ? { borderCollapse: "collapse" } : null,
|
|
1238
|
-
"border-separate": web ? { borderCollapse: "separate" } : null,
|
|
1239
|
-
// List style position (web-only)
|
|
1240
|
-
"list-inside": web ? { listStylePosition: "inside" } : null,
|
|
1241
|
-
"list-outside": web ? { listStylePosition: "outside" } : null,
|
|
1242
|
-
// Font variant numeric (web-only)
|
|
1243
|
-
"normal-nums": web ? { fontVariantNumeric: "normal" } : null,
|
|
1244
|
-
ordinal: web ? { fontVariantNumeric: "ordinal" } : null,
|
|
1245
|
-
"slashed-zero": web ? { fontVariantNumeric: "slashed-zero" } : null,
|
|
1246
|
-
"lining-nums": web ? { fontVariantNumeric: "lining-nums" } : null,
|
|
1247
|
-
"oldstyle-nums": web ? { fontVariantNumeric: "oldstyle-nums" } : null,
|
|
1248
|
-
"proportional-nums": web ? { fontVariantNumeric: "proportional-nums" } : null,
|
|
1249
|
-
"tabular-nums": web ? { fontVariantNumeric: "tabular-nums" } : null,
|
|
1250
|
-
"diagonal-fractions": web ? { fontVariantNumeric: "diagonal-fractions" } : null,
|
|
1251
|
-
"stacked-fractions": web ? { fontVariantNumeric: "stacked-fractions" } : null,
|
|
1252
|
-
// Isolation (web-only)
|
|
1253
|
-
isolate: web ? { isolation: "isolate" } : null,
|
|
1254
|
-
"isolation-auto": web ? { isolation: "auto" } : null,
|
|
1255
|
-
// Backface visibility (both iOS and Android)
|
|
1256
|
-
"backface-visible": { backfaceVisibility: "visible" },
|
|
1257
|
-
"backface-hidden": { backfaceVisibility: "hidden" },
|
|
1258
|
-
// CSS filters — standalone = default/full effect (web-only)
|
|
1259
|
-
grayscale: web ? { "--kb-grayscale": "grayscale(100%)", filter: FILTER_COMPOSE } : null,
|
|
1260
|
-
invert: web ? { "--kb-invert": "invert(100%)", filter: FILTER_COMPOSE } : null,
|
|
1261
|
-
sepia: web ? { "--kb-sepia": "sepia(100%)", filter: FILTER_COMPOSE } : null,
|
|
1262
|
-
// Divide none
|
|
1263
|
-
"divide-none": web ? { __divideX: 0, __divideY: 0 } : null,
|
|
1264
|
-
// Group / peer markers (no-op: no style emitted; just ensures isKnownUtility returns true)
|
|
1265
|
-
group: web ? {} : null,
|
|
1266
|
-
peer: web ? {} : null,
|
|
1267
|
-
// Text-wrap (web-only)
|
|
1268
|
-
"text-wrap": web ? { textWrap: "wrap" } : null,
|
|
1269
|
-
"text-nowrap": web ? { textWrap: "nowrap" } : null,
|
|
1270
|
-
"text-balance": web ? { textWrap: "balance" } : null,
|
|
1271
|
-
"text-pretty": web ? { textWrap: "pretty" } : null,
|
|
1272
|
-
// Screen sizing — dvw/dvh (dynamic viewport units) instead of vw/vh: on mobile
|
|
1273
|
-
// browsers, vh/vw are pinned to the LARGEST viewport size (address bar hidden),
|
|
1274
|
-
// so `h-screen` overflows behind the address bar when it's shown. dvh/dvw track
|
|
1275
|
-
// the actual visible viewport as browser chrome shows/hides. Desktop behavior
|
|
1276
|
-
// is unchanged since there's no dynamic chrome to account for.
|
|
1277
|
-
// (vw/dvw values are web-only; vh/dvh values work cross-platform via spacing scale for h-*)
|
|
1278
|
-
"w-screen": web ? { width: "100dvw" } : null,
|
|
1279
|
-
"min-h-screen": { minHeight: "100dvh" },
|
|
1280
|
-
"max-h-screen": { maxHeight: "100dvh" },
|
|
1281
|
-
"min-w-screen": web ? { minWidth: "100dvw" } : null,
|
|
1282
|
-
"max-w-screen": web ? { maxWidth: "100dvw" } : null,
|
|
1283
|
-
// max-w named container sizes (mirrors Tailwind's container scale)
|
|
1284
|
-
"max-w-none": { maxWidth: "none" },
|
|
1285
|
-
"max-w-xs": { maxWidth: 320 },
|
|
1286
|
-
"max-w-sm": { maxWidth: 384 },
|
|
1287
|
-
"max-w-md": { maxWidth: 448 },
|
|
1288
|
-
"max-w-lg": { maxWidth: 512 },
|
|
1289
|
-
"max-w-xl": { maxWidth: 576 },
|
|
1290
|
-
"max-w-2xl": { maxWidth: 672 },
|
|
1291
|
-
"max-w-3xl": { maxWidth: 768 },
|
|
1292
|
-
"max-w-4xl": { maxWidth: 896 },
|
|
1293
|
-
"max-w-5xl": { maxWidth: 1024 },
|
|
1294
|
-
"max-w-6xl": { maxWidth: 1152 },
|
|
1295
|
-
"max-w-7xl": { maxWidth: 1280 },
|
|
1296
|
-
"max-w-prose": web ? { maxWidth: "65ch" } : null,
|
|
1297
|
-
// Extended cursors (web-only)
|
|
1298
|
-
"cursor-grab": web ? { cursor: "grab" } : null,
|
|
1299
|
-
"cursor-grabbing": web ? { cursor: "grabbing" } : null,
|
|
1300
|
-
"cursor-zoom-in": web ? { cursor: "zoom-in" } : null,
|
|
1301
|
-
"cursor-zoom-out": web ? { cursor: "zoom-out" } : null,
|
|
1302
|
-
"cursor-crosshair": web ? { cursor: "crosshair" } : null,
|
|
1303
|
-
"cursor-help": web ? { cursor: "help" } : null,
|
|
1304
|
-
"cursor-none": web ? { cursor: "none" } : null,
|
|
1305
|
-
// Overflow clip (web-only)
|
|
1306
|
-
"overflow-clip": web ? { overflow: "clip" } : null,
|
|
1307
|
-
"overflow-x-clip": web ? { overflowX: "clip" } : null,
|
|
1308
|
-
"overflow-y-clip": web ? { overflowY: "clip" } : null,
|
|
1309
|
-
// Scroll behavior (web-only)
|
|
1310
|
-
"scroll-smooth": web ? { scrollBehavior: "smooth" } : null,
|
|
1311
|
-
"scroll-auto": web ? { scrollBehavior: "auto" } : null,
|
|
1312
|
-
// Float (web-only)
|
|
1313
|
-
"float-left": web ? { float: "left" } : null,
|
|
1314
|
-
"float-right": web ? { float: "right" } : null,
|
|
1315
|
-
"float-start": web ? { float: "inline-start" } : null,
|
|
1316
|
-
"float-end": web ? { float: "inline-end" } : null,
|
|
1317
|
-
"float-none": web ? { float: "none" } : null,
|
|
1318
|
-
// Clear (web-only)
|
|
1319
|
-
"clear-left": web ? { clear: "left" } : null,
|
|
1320
|
-
"clear-right": web ? { clear: "right" } : null,
|
|
1321
|
-
"clear-both": web ? { clear: "both" } : null,
|
|
1322
|
-
"clear-start": web ? { clear: "inline-start" } : null,
|
|
1323
|
-
"clear-end": web ? { clear: "inline-end" } : null,
|
|
1324
|
-
"clear-none": web ? { clear: "none" } : null,
|
|
1325
|
-
// Vertical align (web-only)
|
|
1326
|
-
"align-baseline": web ? { verticalAlign: "baseline" } : null,
|
|
1327
|
-
"align-top": web ? { verticalAlign: "top" } : null,
|
|
1328
|
-
"align-middle": web ? { verticalAlign: "middle" } : null,
|
|
1329
|
-
"align-bottom": web ? { verticalAlign: "bottom" } : null,
|
|
1330
|
-
"align-text-top": web ? { verticalAlign: "text-top" } : null,
|
|
1331
|
-
"align-text-bottom": web ? { verticalAlign: "text-bottom" } : null,
|
|
1332
|
-
"align-sub": web ? { verticalAlign: "sub" } : null,
|
|
1333
|
-
"align-super": web ? { verticalAlign: "super" } : null,
|
|
1334
|
-
// Touch action (web-only)
|
|
1335
|
-
"touch-auto": web ? { touchAction: "auto" } : null,
|
|
1336
|
-
"touch-none": web ? { touchAction: "none" } : null,
|
|
1337
|
-
"touch-pan-x": web ? { touchAction: "pan-x" } : null,
|
|
1338
|
-
"touch-pan-y": web ? { touchAction: "pan-y" } : null,
|
|
1339
|
-
"touch-pan-left": web ? { touchAction: "pan-left" } : null,
|
|
1340
|
-
"touch-pan-right": web ? { touchAction: "pan-right" } : null,
|
|
1341
|
-
"touch-pan-up": web ? { touchAction: "pan-up" } : null,
|
|
1342
|
-
"touch-pan-down": web ? { touchAction: "pan-down" } : null,
|
|
1343
|
-
"touch-pinch-zoom": web ? { touchAction: "pinch-zoom" } : null,
|
|
1344
|
-
"touch-manipulation": web ? { touchAction: "manipulation" } : null
|
|
1345
|
-
};
|
|
1346
|
-
}
|
|
1347
|
-
function getStandalone() {
|
|
1348
|
-
if (!_standalone) _standalone = buildStandalone();
|
|
1349
|
-
return _standalone;
|
|
1350
|
-
}
|
|
1351
|
-
function makeSpacingResolver(prop) {
|
|
1352
|
-
return ({ value, negative, isArbitrary }, { spacing }) => {
|
|
1353
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
1354
|
-
return v !== null ? { [prop]: v } : null;
|
|
1355
|
-
};
|
|
1356
|
-
}
|
|
1357
|
-
var PADDING_MARGIN_PROPS = {
|
|
1358
|
-
p: "padding",
|
|
1359
|
-
px: "paddingHorizontal",
|
|
1360
|
-
py: "paddingVertical",
|
|
1361
|
-
pt: "paddingTop",
|
|
1362
|
-
pr: "paddingRight",
|
|
1363
|
-
pb: "paddingBottom",
|
|
1364
|
-
pl: "paddingLeft",
|
|
1365
|
-
m: "margin",
|
|
1366
|
-
mx: "marginHorizontal",
|
|
1367
|
-
my: "marginVertical",
|
|
1368
|
-
mt: "marginTop",
|
|
1369
|
-
mr: "marginRight",
|
|
1370
|
-
mb: "marginBottom",
|
|
1371
|
-
ml: "marginLeft"
|
|
1372
|
-
};
|
|
1373
|
-
function makeBorderSideResolver(widthProp, colorProp) {
|
|
1374
|
-
return ({ value, isArbitrary }, { colors, borderWidth }) => {
|
|
1375
|
-
if (!value) return { [widthProp]: 1 };
|
|
1376
|
-
if (isArbitrary) {
|
|
1377
|
-
const w2 = toNativeValue(value);
|
|
1378
|
-
if (typeof w2 === "number") return { [widthProp]: w2 };
|
|
1379
|
-
return { [colorProp]: value };
|
|
1380
|
-
}
|
|
1381
|
-
const color = resolveColor(value, colors, false);
|
|
1382
|
-
if (color) return { [colorProp]: color };
|
|
1383
|
-
const w = borderWidth[value];
|
|
1384
|
-
return w !== void 0 ? { [widthProp]: w } : null;
|
|
1385
|
-
};
|
|
1386
|
-
}
|
|
1387
|
-
var BORDER_SIDE_PROPS = {
|
|
1388
|
-
"border-t": ["borderTopWidth", "borderTopColor"],
|
|
1389
|
-
"border-r": ["borderRightWidth", "borderRightColor"],
|
|
1390
|
-
"border-b": ["borderBottomWidth", "borderBottomColor"],
|
|
1391
|
-
"border-l": ["borderLeftWidth", "borderLeftColor"]
|
|
1392
|
-
};
|
|
1393
|
-
function keyframeDeclToCSS(decl) {
|
|
1394
|
-
return Object.entries(decl).map(([prop, val]) => `${prop.replace(/([A-Z])/g, "-$1").toLowerCase()}: ${val}`).join("; ");
|
|
1395
|
-
}
|
|
1396
|
-
function buildKeyframeCSS(name, steps) {
|
|
1397
|
-
const body = Object.entries(steps).map(([selector, decl]) => `${selector} { ${keyframeDeclToCSS(decl)} }`).join(" ");
|
|
1398
|
-
return `@keyframes ${name} { ${body} }`;
|
|
1399
|
-
}
|
|
1400
|
-
var BUILTIN_ANIMATIONS = {
|
|
1401
|
-
none: { animation: "none" },
|
|
1402
|
-
spin: {
|
|
1403
|
-
animation: "kb-spin 1s linear infinite",
|
|
1404
|
-
__keyframe: "@keyframes kb-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }"
|
|
1405
|
-
},
|
|
1406
|
-
ping: {
|
|
1407
|
-
animation: "kb-ping 1s cubic-bezier(0,0,0.2,1) infinite",
|
|
1408
|
-
__keyframe: "@keyframes kb-ping { 75%, 100% { transform: scale(2); opacity: 0 } }"
|
|
1409
|
-
},
|
|
1410
|
-
pulse: {
|
|
1411
|
-
animation: "kb-pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
|
|
1412
|
-
__keyframe: "@keyframes kb-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }"
|
|
1413
|
-
},
|
|
1414
|
-
bounce: {
|
|
1415
|
-
animation: "kb-bounce 1s infinite",
|
|
1416
|
-
__keyframe: "@keyframes kb-bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8,0,1,1) } 50% { transform: none; animation-timing-function: cubic-bezier(0,0,0.2,1) } }"
|
|
1417
|
-
}
|
|
1418
|
-
};
|
|
1419
|
-
function buildAnimationValue(animation, keyframes) {
|
|
1420
|
-
const words = animation.trim().split(/\s+/);
|
|
1421
|
-
const name = words[0];
|
|
1422
|
-
if (!name) return { animation };
|
|
1423
|
-
const builtin = BUILTIN_ANIMATIONS[name];
|
|
1424
|
-
if (builtin?.__keyframe) {
|
|
1425
|
-
const kbName = builtin.animation.split(/\s+/, 1)[0];
|
|
1426
|
-
return { animation: [kbName, ...words.slice(1)].join(" "), __keyframe: builtin.__keyframe };
|
|
1427
|
-
}
|
|
1428
|
-
const steps = keyframes?.[name];
|
|
1429
|
-
return steps ? { animation, __keyframe: buildKeyframeCSS(name, steps) } : { animation };
|
|
1430
|
-
}
|
|
1431
|
-
var RESOLVERS = {
|
|
1432
|
-
// ── Background ─────────────────────────────────────────────────────────────
|
|
1433
|
-
bg: ({ value, isArbitrary }, { colors }) => {
|
|
1434
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1435
|
-
if (!color) return null;
|
|
1436
|
-
return { backgroundColor: getEffectiveIsWeb() ? withOpacityVar(color, "--bg-opacity") : color };
|
|
1437
|
-
},
|
|
1438
|
-
"bg-opacity": ({ value, isArbitrary }, _) => {
|
|
1439
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1440
|
-
const n = parseFloat(value);
|
|
1441
|
-
if (isNaN(n)) return null;
|
|
1442
|
-
const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
|
|
1443
|
-
return { "--bg-opacity": v };
|
|
1444
|
-
},
|
|
1445
|
-
// ── Text ───────────────────────────────────────────────────────────────────
|
|
1446
|
-
text: ({ value, isArbitrary }, { colors, fontSize }) => {
|
|
1447
|
-
const size = resolveFontSize(value, fontSize, false);
|
|
1448
|
-
if (!isArbitrary && size !== null) return { fontSize: size };
|
|
1449
|
-
if (isArbitrary) {
|
|
1450
|
-
if (/^\d/.test(value) || /^(calc|min|max|clamp)/.test(value)) {
|
|
1451
|
-
return { fontSize: getEffectiveIsWeb() ? value : toNativeValue(value) };
|
|
1452
|
-
}
|
|
1453
|
-
return { color: getEffectiveIsWeb() ? withOpacityVar(value, "--text-opacity") : value };
|
|
1454
|
-
}
|
|
1455
|
-
const color = resolveColor(value, colors, false);
|
|
1456
|
-
if (!color) return null;
|
|
1457
|
-
return { color: getEffectiveIsWeb() ? withOpacityVar(color, "--text-opacity") : color };
|
|
1458
|
-
},
|
|
1459
|
-
"text-opacity": ({ value, isArbitrary }, _) => {
|
|
1460
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1461
|
-
const n = parseFloat(value);
|
|
1462
|
-
if (isNaN(n)) return null;
|
|
1463
|
-
const v = isArbitrary ? n > 1 ? n / 100 : n : n / 100;
|
|
1464
|
-
return { "--text-opacity": v };
|
|
1465
|
-
},
|
|
1466
|
-
// ── Padding & margin ───────────────────────────────────────────────────────
|
|
1467
|
-
// Generated below via makeSpacingResolver() — see PADDING_MARGIN_PROPS.
|
|
1468
|
-
// ── Sizing ─────────────────────────────────────────────────────────────────
|
|
1469
|
-
w: ({ value, isArbitrary }, { spacing }) => {
|
|
1470
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1471
|
-
return v !== null ? { width: v } : null;
|
|
1472
|
-
},
|
|
1473
|
-
h: ({ value, isArbitrary }, { spacing }) => {
|
|
1474
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1475
|
-
return v !== null ? { height: v } : null;
|
|
1476
|
-
},
|
|
1477
|
-
"min-w": ({ value, isArbitrary }, { spacing }) => {
|
|
1478
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1479
|
-
return v !== null ? { minWidth: v } : null;
|
|
1480
|
-
},
|
|
1481
|
-
"min-h": ({ value, isArbitrary }, { spacing }) => {
|
|
1482
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1483
|
-
return v !== null ? { minHeight: v } : null;
|
|
1484
|
-
},
|
|
1485
|
-
"max-w": ({ value, isArbitrary }, { spacing }) => {
|
|
1486
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1487
|
-
return v !== null ? { maxWidth: v } : null;
|
|
1488
|
-
},
|
|
1489
|
-
"max-h": ({ value, isArbitrary }, { spacing }) => {
|
|
1490
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
1491
|
-
return v !== null ? { maxHeight: v } : null;
|
|
1492
|
-
},
|
|
1493
|
-
// ── Border width ───────────────────────────────────────────────────────────
|
|
1494
|
-
border: ({ value, isArbitrary }, { colors, borderWidth, spacing }) => {
|
|
1495
|
-
if (!value) return { borderWidth: borderWidth["DEFAULT"] ?? 1 };
|
|
1496
|
-
if (isArbitrary) {
|
|
1497
|
-
const w2 = toNativeValue(value);
|
|
1498
|
-
if (typeof w2 === "number") return { borderWidth: w2 };
|
|
1499
|
-
return { borderColor: value };
|
|
1500
|
-
}
|
|
1501
|
-
const color = resolveColor(value, colors, false);
|
|
1502
|
-
if (color) return { borderColor: color };
|
|
1503
|
-
const w = borderWidth[value] ?? spacing[value];
|
|
1504
|
-
if (w !== void 0) {
|
|
1505
|
-
const numW = typeof w === "number" ? w : parseFloat(String(w));
|
|
1506
|
-
if (isNaN(numW)) return null;
|
|
1507
|
-
return { borderWidth: numW };
|
|
1508
|
-
}
|
|
1509
|
-
return null;
|
|
1510
|
-
},
|
|
1511
|
-
// border-t/-r/-b/-l generated below via makeBorderSideResolver() — see BORDER_SIDE_PROPS.
|
|
1512
|
-
// ── Border radius ──────────────────────────────────────────────────────────
|
|
1513
|
-
rounded: ({ value, isArbitrary }, { borderRadius }) => {
|
|
1514
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1515
|
-
return r !== null ? { borderRadius: r } : null;
|
|
1516
|
-
},
|
|
1517
|
-
"rounded-t": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1518
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1519
|
-
return r !== null ? { borderTopLeftRadius: r, borderTopRightRadius: r } : null;
|
|
1520
|
-
},
|
|
1521
|
-
"rounded-r": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1522
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1523
|
-
return r !== null ? { borderTopRightRadius: r, borderBottomRightRadius: r } : null;
|
|
1524
|
-
},
|
|
1525
|
-
"rounded-b": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1526
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1527
|
-
return r !== null ? { borderBottomLeftRadius: r, borderBottomRightRadius: r } : null;
|
|
1528
|
-
},
|
|
1529
|
-
"rounded-l": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1530
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1531
|
-
return r !== null ? { borderTopLeftRadius: r, borderBottomLeftRadius: r } : null;
|
|
1532
|
-
},
|
|
1533
|
-
"rounded-tl": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1534
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1535
|
-
return r !== null ? { borderTopLeftRadius: r } : null;
|
|
1536
|
-
},
|
|
1537
|
-
"rounded-tr": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1538
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1539
|
-
return r !== null ? { borderTopRightRadius: r } : null;
|
|
1540
|
-
},
|
|
1541
|
-
"rounded-bl": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1542
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1543
|
-
return r !== null ? { borderBottomLeftRadius: r } : null;
|
|
1544
|
-
},
|
|
1545
|
-
"rounded-br": ({ value, isArbitrary }, { borderRadius }) => {
|
|
1546
|
-
const r = resolveRadius(value, borderRadius, isArbitrary);
|
|
1547
|
-
return r !== null ? { borderBottomRightRadius: r } : null;
|
|
1548
|
-
},
|
|
1549
|
-
// ── Grid (responsive column count: grid-1 … grid-12, or arbitrary) ───────
|
|
1550
|
-
grid: ({ value, isArbitrary }) => {
|
|
1551
|
-
if (!value) return null;
|
|
1552
|
-
if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
|
|
1553
|
-
const n = parseInt(value, 10);
|
|
1554
|
-
if (isNaN(n) || n < 1 || n > 12) return null;
|
|
1555
|
-
return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
|
|
1556
|
-
},
|
|
1557
|
-
// ── Grid template columns/rows (Tailwind-style aliases, web-only) ──────────
|
|
1558
|
-
"grid-cols": ({ value, isArbitrary }) => {
|
|
1559
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1560
|
-
if (!value) return null;
|
|
1561
|
-
if (isArbitrary) return { display: "grid", gridTemplateColumns: value };
|
|
1562
|
-
if (value === "none") return { display: "grid", gridTemplateColumns: "none" };
|
|
1563
|
-
const n = parseInt(value, 10);
|
|
1564
|
-
if (isNaN(n) || n < 1 || n > 12) return null;
|
|
1565
|
-
return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
|
|
1566
|
-
},
|
|
1567
|
-
"grid-rows": ({ value, isArbitrary }) => {
|
|
1568
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1569
|
-
if (!value) return null;
|
|
1570
|
-
if (isArbitrary) return { gridTemplateRows: value };
|
|
1571
|
-
if (value === "none") return { gridTemplateRows: "none" };
|
|
1572
|
-
const n = parseInt(value, 10);
|
|
1573
|
-
if (isNaN(n) || n < 1) return null;
|
|
1574
|
-
return { gridTemplateRows: `repeat(${n}, minmax(0, 1fr))` };
|
|
1575
|
-
},
|
|
1576
|
-
// ── Grid auto flow (web-only) ─────────────────────────────────────────────
|
|
1577
|
-
"grid-flow": ({ value }) => {
|
|
1578
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1579
|
-
const flows = {
|
|
1580
|
-
row: "row",
|
|
1581
|
-
col: "column",
|
|
1582
|
-
dense: "dense",
|
|
1583
|
-
"row-dense": "row dense",
|
|
1584
|
-
"col-dense": "column dense"
|
|
1585
|
-
};
|
|
1586
|
-
const flow = flows[value];
|
|
1587
|
-
return flow ? { gridAutoFlow: flow } : null;
|
|
1588
|
-
},
|
|
1589
|
-
// ── Grid auto sizing (web-only) ───────────────────────────────────────────
|
|
1590
|
-
"auto-cols": ({ value, isArbitrary }) => {
|
|
1591
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1592
|
-
if (isArbitrary) return { gridAutoColumns: value };
|
|
1593
|
-
const presets = {
|
|
1594
|
-
auto: "auto",
|
|
1595
|
-
min: "min-content",
|
|
1596
|
-
max: "max-content",
|
|
1597
|
-
fr: "minmax(0, 1fr)"
|
|
1598
|
-
};
|
|
1599
|
-
const v = presets[value];
|
|
1600
|
-
return v ? { gridAutoColumns: v } : null;
|
|
1601
|
-
},
|
|
1602
|
-
"auto-rows": ({ value, isArbitrary }) => {
|
|
1603
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1604
|
-
if (isArbitrary) return { gridAutoRows: value };
|
|
1605
|
-
const presets = {
|
|
1606
|
-
auto: "auto",
|
|
1607
|
-
min: "min-content",
|
|
1608
|
-
max: "max-content",
|
|
1609
|
-
fr: "minmax(0, 1fr)"
|
|
1610
|
-
};
|
|
1611
|
-
const v = presets[value];
|
|
1612
|
-
return v ? { gridAutoRows: v } : null;
|
|
1613
|
-
},
|
|
1614
|
-
// ── Grid column placement (web-only) ──────────────────────────────────────
|
|
1615
|
-
"col-span": ({ value }) => {
|
|
1616
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1617
|
-
if (value === "full") return { gridColumn: "1 / -1" };
|
|
1618
|
-
const n = parseInt(value, 10);
|
|
1619
|
-
return isNaN(n) ? null : { gridColumn: `span ${n} / span ${n}` };
|
|
1620
|
-
},
|
|
1621
|
-
"col-start": ({ value, isArbitrary }) => {
|
|
1622
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1623
|
-
if (value === "auto") return { gridColumnStart: "auto" };
|
|
1624
|
-
if (isArbitrary) return { gridColumnStart: value };
|
|
1625
|
-
const n = parseInt(value, 10);
|
|
1626
|
-
return isNaN(n) ? null : { gridColumnStart: n };
|
|
1627
|
-
},
|
|
1628
|
-
"col-end": ({ value, isArbitrary }) => {
|
|
1629
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1630
|
-
if (value === "auto") return { gridColumnEnd: "auto" };
|
|
1631
|
-
if (isArbitrary) return { gridColumnEnd: value };
|
|
1632
|
-
const n = parseInt(value, 10);
|
|
1633
|
-
return isNaN(n) ? null : { gridColumnEnd: n };
|
|
1634
|
-
},
|
|
1635
|
-
col: ({ value, isArbitrary }) => {
|
|
1636
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1637
|
-
if (!value || value === "auto") return { gridColumn: "auto" };
|
|
1638
|
-
if (isArbitrary) return { gridColumn: value };
|
|
1639
|
-
return null;
|
|
1640
|
-
},
|
|
1641
|
-
// ── Grid row placement (web-only) ─────────────────────────────────────────
|
|
1642
|
-
"row-span": ({ value }) => {
|
|
1643
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1644
|
-
if (value === "full") return { gridRow: "1 / -1" };
|
|
1645
|
-
const n = parseInt(value, 10);
|
|
1646
|
-
return isNaN(n) ? null : { gridRow: `span ${n} / span ${n}` };
|
|
1647
|
-
},
|
|
1648
|
-
"row-start": ({ value, isArbitrary }) => {
|
|
1649
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1650
|
-
if (value === "auto") return { gridRowStart: "auto" };
|
|
1651
|
-
if (isArbitrary) return { gridRowStart: value };
|
|
1652
|
-
const n = parseInt(value, 10);
|
|
1653
|
-
return isNaN(n) ? null : { gridRowStart: n };
|
|
1654
|
-
},
|
|
1655
|
-
"row-end": ({ value, isArbitrary }) => {
|
|
1656
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1657
|
-
if (value === "auto") return { gridRowEnd: "auto" };
|
|
1658
|
-
if (isArbitrary) return { gridRowEnd: value };
|
|
1659
|
-
const n = parseInt(value, 10);
|
|
1660
|
-
return isNaN(n) ? null : { gridRowEnd: n };
|
|
1661
|
-
},
|
|
1662
|
-
row: ({ value, isArbitrary }) => {
|
|
1663
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1664
|
-
if (!value || value === "auto") return { gridRow: "auto" };
|
|
1665
|
-
if (isArbitrary) return { gridRow: value };
|
|
1666
|
-
return null;
|
|
1667
|
-
},
|
|
1668
|
-
// ── Grid alignment (web-only) ──────────────────────────────────────────────
|
|
1669
|
-
// place-items is shorthand for align-items + justify-items on a grid container
|
|
1670
|
-
"place-items": ({ value }) => {
|
|
1671
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1672
|
-
const map = {
|
|
1673
|
-
start: "start",
|
|
1674
|
-
end: "end",
|
|
1675
|
-
center: "center",
|
|
1676
|
-
stretch: "stretch",
|
|
1677
|
-
baseline: "baseline"
|
|
1678
|
-
};
|
|
1679
|
-
return map[value] ? { placeItems: map[value] } : null;
|
|
1680
|
-
},
|
|
1681
|
-
// place-content is shorthand for align-content + justify-content on a grid container
|
|
1682
|
-
"place-content": ({ value }) => {
|
|
1683
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1684
|
-
const map = {
|
|
1685
|
-
start: "start",
|
|
1686
|
-
end: "end",
|
|
1687
|
-
center: "center",
|
|
1688
|
-
stretch: "stretch",
|
|
1689
|
-
between: "space-between",
|
|
1690
|
-
around: "space-around",
|
|
1691
|
-
evenly: "space-evenly",
|
|
1692
|
-
baseline: "baseline"
|
|
1693
|
-
};
|
|
1694
|
-
return map[value] ? { placeContent: map[value] } : null;
|
|
1695
|
-
},
|
|
1696
|
-
// justify-items controls inline-axis alignment of grid items within their cells
|
|
1697
|
-
"justify-items": ({ value }) => {
|
|
1698
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1699
|
-
const map = {
|
|
1700
|
-
start: "start",
|
|
1701
|
-
end: "end",
|
|
1702
|
-
center: "center",
|
|
1703
|
-
stretch: "stretch"
|
|
1704
|
-
};
|
|
1705
|
-
return map[value] ? { justifyItems: map[value] } : null;
|
|
1706
|
-
},
|
|
1707
|
-
// place-self is shorthand for align-self + justify-self on a grid item
|
|
1708
|
-
"place-self": ({ value }) => {
|
|
1709
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1710
|
-
const map = {
|
|
1711
|
-
auto: "auto",
|
|
1712
|
-
start: "start",
|
|
1713
|
-
end: "end",
|
|
1714
|
-
center: "center",
|
|
1715
|
-
stretch: "stretch"
|
|
1716
|
-
};
|
|
1717
|
-
return map[value] ? { placeSelf: map[value] } : null;
|
|
1718
|
-
},
|
|
1719
|
-
// justify-self controls inline-axis self-alignment of a grid item
|
|
1720
|
-
"justify-self": ({ value }) => {
|
|
1721
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1722
|
-
const map = {
|
|
1723
|
-
auto: "auto",
|
|
1724
|
-
start: "start",
|
|
1725
|
-
end: "end",
|
|
1726
|
-
center: "center",
|
|
1727
|
-
stretch: "stretch"
|
|
1728
|
-
};
|
|
1729
|
-
return map[value] ? { justifySelf: map[value] } : null;
|
|
1730
|
-
},
|
|
1731
|
-
// ── CSS Filters (composable via CSS variables, web-only) ─────────────────
|
|
1732
|
-
blur: ({ value, isArbitrary }) => {
|
|
1733
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1734
|
-
const sizes = {
|
|
1735
|
-
"": "blur(8px)",
|
|
1736
|
-
sm: "blur(4px)",
|
|
1737
|
-
md: "blur(12px)",
|
|
1738
|
-
lg: "blur(16px)",
|
|
1739
|
-
xl: "blur(24px)",
|
|
1740
|
-
"2xl": "blur(40px)",
|
|
1741
|
-
"3xl": "blur(64px)"
|
|
1742
|
-
};
|
|
1743
|
-
if (value === "none") return { "--kb-blur": "", filter: FILTER_COMPOSE };
|
|
1744
|
-
const v = isArbitrary ? `blur(${value})` : sizes[value];
|
|
1745
|
-
return v !== void 0 ? { "--kb-blur": v, filter: FILTER_COMPOSE } : null;
|
|
1746
|
-
},
|
|
1747
|
-
brightness: ({ value, isArbitrary }) => {
|
|
1748
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1749
|
-
const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
|
|
1750
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-brightness": v, filter: FILTER_COMPOSE };
|
|
1751
|
-
},
|
|
1752
|
-
contrast: ({ value, isArbitrary }) => {
|
|
1753
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1754
|
-
const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
|
|
1755
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-contrast": v, filter: FILTER_COMPOSE };
|
|
1756
|
-
},
|
|
1757
|
-
grayscale: ({ value }) => {
|
|
1758
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1759
|
-
const v = value === "0" ? "grayscale(0)" : "grayscale(100%)";
|
|
1760
|
-
return { "--kb-grayscale": v, filter: FILTER_COMPOSE };
|
|
1761
|
-
},
|
|
1762
|
-
"hue-rotate": ({ value, negative, isArbitrary }) => {
|
|
1763
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1764
|
-
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
1765
|
-
if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
|
|
1766
|
-
return { "--kb-hue-rotate": `hue-rotate(${deg})`, filter: FILTER_COMPOSE };
|
|
1767
|
-
},
|
|
1768
|
-
invert: ({ value }) => {
|
|
1769
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1770
|
-
const v = value === "0" ? "invert(0)" : "invert(100%)";
|
|
1771
|
-
return { "--kb-invert": v, filter: FILTER_COMPOSE };
|
|
1772
|
-
},
|
|
1773
|
-
saturate: ({ value, isArbitrary }) => {
|
|
1774
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1775
|
-
const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
|
|
1776
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-saturate": v, filter: FILTER_COMPOSE };
|
|
1777
|
-
},
|
|
1778
|
-
sepia: ({ value }) => {
|
|
1779
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1780
|
-
const v = value === "0" ? "sepia(0)" : "sepia(100%)";
|
|
1781
|
-
return { "--kb-sepia": v, filter: FILTER_COMPOSE };
|
|
1782
|
-
},
|
|
1783
|
-
"drop-shadow": ({ value, isArbitrary }) => {
|
|
1784
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1785
|
-
if (isArbitrary) return { "--kb-drop-shadow": `drop-shadow(${value.replace(/_/g, " ")})`, filter: FILTER_COMPOSE };
|
|
1786
|
-
const presets = {
|
|
1787
|
-
"": "drop-shadow(0 1px 2px rgb(0 0 0/0.1)) drop-shadow(0 1px 1px rgb(0 0 0/0.06))",
|
|
1788
|
-
sm: "drop-shadow(0 1px 1px rgb(0 0 0/0.05))",
|
|
1789
|
-
md: "drop-shadow(0 4px 3px rgb(0 0 0/0.07)) drop-shadow(0 2px 2px rgb(0 0 0/0.06))",
|
|
1790
|
-
lg: "drop-shadow(0 10px 8px rgb(0 0 0/0.04)) drop-shadow(0 4px 3px rgb(0 0 0/0.1))",
|
|
1791
|
-
xl: "drop-shadow(0 20px 13px rgb(0 0 0/0.03)) drop-shadow(0 8px 5px rgb(0 0 0/0.08))",
|
|
1792
|
-
"2xl": "drop-shadow(0 25px 25px rgb(0 0 0/0.15))",
|
|
1793
|
-
none: "drop-shadow(0 0 #0000)"
|
|
1794
|
-
};
|
|
1795
|
-
const v = presets[value];
|
|
1796
|
-
return v !== void 0 ? { "--kb-drop-shadow": v, filter: FILTER_COMPOSE } : null;
|
|
1797
|
-
},
|
|
1798
|
-
// Arbitrary full filter string: filter-[blur(4px)_grayscale(1)]
|
|
1799
|
-
filter: ({ value, isArbitrary }) => {
|
|
1800
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1801
|
-
if (isArbitrary) return { filter: value.replace(/_/g, " ") };
|
|
1802
|
-
if (value === "none") return { filter: "none" };
|
|
1803
|
-
return null;
|
|
1804
|
-
},
|
|
1805
|
-
// ── Backdrop Filters (composable via CSS variables, web-only) ────────────
|
|
1806
|
-
"backdrop-blur": ({ value, isArbitrary }) => {
|
|
1807
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1808
|
-
const sizes = {
|
|
1809
|
-
"": "blur(8px)",
|
|
1810
|
-
sm: "blur(4px)",
|
|
1811
|
-
md: "blur(12px)",
|
|
1812
|
-
lg: "blur(16px)",
|
|
1813
|
-
xl: "blur(24px)",
|
|
1814
|
-
"2xl": "blur(40px)",
|
|
1815
|
-
"3xl": "blur(64px)"
|
|
1816
|
-
};
|
|
1817
|
-
if (value === "none") return { "--kb-backdrop-blur": "", backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1818
|
-
const v = isArbitrary ? `blur(${value})` : sizes[value];
|
|
1819
|
-
return v !== void 0 ? { "--kb-backdrop-blur": v, backdropFilter: BACKDROP_FILTER_COMPOSE } : null;
|
|
1820
|
-
},
|
|
1821
|
-
"backdrop-brightness": ({ value, isArbitrary }) => {
|
|
1822
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1823
|
-
const v = isArbitrary ? `brightness(${value})` : `brightness(${parseFloat(value) / 100})`;
|
|
1824
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-brightness": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1825
|
-
},
|
|
1826
|
-
"backdrop-contrast": ({ value, isArbitrary }) => {
|
|
1827
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1828
|
-
const v = isArbitrary ? `contrast(${value})` : `contrast(${parseFloat(value) / 100})`;
|
|
1829
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-contrast": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1830
|
-
},
|
|
1831
|
-
"backdrop-grayscale": ({ value }) => {
|
|
1832
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1833
|
-
return { "--kb-backdrop-grayscale": value === "0" ? "grayscale(0)" : "grayscale(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1834
|
-
},
|
|
1835
|
-
"backdrop-hue-rotate": ({ value, negative, isArbitrary }) => {
|
|
1836
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1837
|
-
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
1838
|
-
if (isNaN(parseFloat(deg)) && !isArbitrary) return null;
|
|
1839
|
-
return { "--kb-backdrop-hue-rotate": `hue-rotate(${deg})`, backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1840
|
-
},
|
|
1841
|
-
"backdrop-invert": ({ value }) => {
|
|
1842
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1843
|
-
return { "--kb-backdrop-invert": value === "0" ? "invert(0)" : "invert(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1844
|
-
},
|
|
1845
|
-
"backdrop-opacity": ({ value, isArbitrary }) => {
|
|
1846
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1847
|
-
const v = isArbitrary ? `opacity(${value})` : `opacity(${parseFloat(value) / 100})`;
|
|
1848
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-opacity": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1849
|
-
},
|
|
1850
|
-
"backdrop-saturate": ({ value, isArbitrary }) => {
|
|
1851
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1852
|
-
const v = isArbitrary ? `saturate(${value})` : `saturate(${parseFloat(value) / 100})`;
|
|
1853
|
-
return isNaN(parseFloat(value)) && !isArbitrary ? null : { "--kb-backdrop-saturate": v, backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1854
|
-
},
|
|
1855
|
-
"backdrop-sepia": ({ value }) => {
|
|
1856
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1857
|
-
return { "--kb-backdrop-sepia": value === "0" ? "sepia(0)" : "sepia(100%)", backdropFilter: BACKDROP_FILTER_COMPOSE };
|
|
1858
|
-
},
|
|
1859
|
-
"backdrop-filter": ({ value, isArbitrary }) => {
|
|
1860
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1861
|
-
if (isArbitrary) return { backdropFilter: value.replace(/_/g, " ") };
|
|
1862
|
-
if (value === "none") return { backdropFilter: "none" };
|
|
1863
|
-
return null;
|
|
1864
|
-
},
|
|
1865
|
-
// ── Background gradient (CSS variable gradient stops, web-only) ──────────
|
|
1866
|
-
"bg-gradient-to": ({ value }) => {
|
|
1867
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1868
|
-
const directions = {
|
|
1869
|
-
t: "to top",
|
|
1870
|
-
tr: "to top right",
|
|
1871
|
-
r: "to right",
|
|
1872
|
-
br: "to bottom right",
|
|
1873
|
-
b: "to bottom",
|
|
1874
|
-
bl: "to bottom left",
|
|
1875
|
-
l: "to left",
|
|
1876
|
-
tl: "to top left"
|
|
1877
|
-
};
|
|
1878
|
-
const dir = directions[value];
|
|
1879
|
-
if (!dir) return null;
|
|
1880
|
-
return {
|
|
1881
|
-
backgroundImage: `linear-gradient(${dir}, var(--kb-gradient-from, transparent), var(--kb-gradient-stops, transparent))`
|
|
1882
|
-
};
|
|
1883
|
-
},
|
|
1884
|
-
from: ({ value, isArbitrary }, { colors }) => {
|
|
1885
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1886
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1887
|
-
if (!color) return null;
|
|
1888
|
-
return {
|
|
1889
|
-
"--kb-gradient-from": color,
|
|
1890
|
-
"--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-to, transparent)`
|
|
1891
|
-
};
|
|
1892
|
-
},
|
|
1893
|
-
via: ({ value, isArbitrary }, { colors }) => {
|
|
1894
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1895
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1896
|
-
if (!color) return null;
|
|
1897
|
-
return {
|
|
1898
|
-
"--kb-gradient-via": color,
|
|
1899
|
-
"--kb-gradient-stops": `var(--kb-gradient-from), var(--kb-gradient-via), var(--kb-gradient-to, transparent)`
|
|
1900
|
-
};
|
|
1901
|
-
},
|
|
1902
|
-
to: ({ value, isArbitrary }, { colors }) => {
|
|
1903
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1904
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
1905
|
-
if (!color) return null;
|
|
1906
|
-
return { "--kb-gradient-to": color };
|
|
1907
|
-
},
|
|
1908
|
-
// ── Transform extras (web-only) ───────────────────────────────────────────
|
|
1909
|
-
"skew-x": ({ value, negative, isArbitrary }) => {
|
|
1910
|
-
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
1911
|
-
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
1912
|
-
return getEffectiveIsWeb() ? { transform: `skewX(${deg})` } : { transform: [{ skewX: deg }] };
|
|
1913
|
-
},
|
|
1914
|
-
"skew-y": ({ value, negative, isArbitrary }) => {
|
|
1915
|
-
const deg = isArbitrary ? value : `${(negative ? -1 : 1) * parseFloat(value)}deg`;
|
|
1916
|
-
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
1917
|
-
return getEffectiveIsWeb() ? { transform: `skewY(${deg})` } : { transform: [{ skewY: deg }] };
|
|
1918
|
-
},
|
|
1919
|
-
// Arbitrary full transform string: transform-[rotate(45deg)_scale(1.5)]
|
|
1920
|
-
transform: ({ value, isArbitrary }) => {
|
|
1921
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1922
|
-
if (isArbitrary) return { transform: value.replace(/_/g, " ") };
|
|
1923
|
-
if (value === "none") return { transform: "none" };
|
|
1924
|
-
return null;
|
|
1925
|
-
},
|
|
1926
|
-
// Transform origin
|
|
1927
|
-
origin: ({ value, isArbitrary }) => {
|
|
1928
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1929
|
-
if (isArbitrary) return { transformOrigin: value.replace(/_/g, " ") };
|
|
1930
|
-
const origins = {
|
|
1931
|
-
center: "center",
|
|
1932
|
-
top: "top",
|
|
1933
|
-
"top-right": "top right",
|
|
1934
|
-
right: "right",
|
|
1935
|
-
"bottom-right": "bottom right",
|
|
1936
|
-
bottom: "bottom",
|
|
1937
|
-
"bottom-left": "bottom left",
|
|
1938
|
-
left: "left",
|
|
1939
|
-
"top-left": "top left"
|
|
1940
|
-
};
|
|
1941
|
-
return origins[value] ? { transformOrigin: origins[value] } : null;
|
|
1942
|
-
},
|
|
1943
|
-
// ── Text decoration advanced (web-only) ───────────────────────────────────
|
|
1944
|
-
decoration: ({ value, isArbitrary }, { colors }) => {
|
|
1945
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1946
|
-
if (isArbitrary) {
|
|
1947
|
-
if (/^\d/.test(value) || value.startsWith("calc(")) return { textDecorationThickness: value };
|
|
1948
|
-
return { textDecorationColor: value };
|
|
1949
|
-
}
|
|
1950
|
-
const thickTokens = {
|
|
1951
|
-
auto: "auto",
|
|
1952
|
-
"from-font": "from-font",
|
|
1953
|
-
"0": "0px",
|
|
1954
|
-
"1": "1px",
|
|
1955
|
-
"2": "2px",
|
|
1956
|
-
"4": "4px",
|
|
1957
|
-
"8": "8px"
|
|
1958
|
-
};
|
|
1959
|
-
if (value in thickTokens) return { textDecorationThickness: thickTokens[value] };
|
|
1960
|
-
const styleTokens = {
|
|
1961
|
-
solid: "solid",
|
|
1962
|
-
dashed: "dashed",
|
|
1963
|
-
dotted: "dotted",
|
|
1964
|
-
double: "double",
|
|
1965
|
-
wavy: "wavy"
|
|
1966
|
-
};
|
|
1967
|
-
if (value in styleTokens) return { textDecorationStyle: styleTokens[value] };
|
|
1968
|
-
const color = resolveColor(value, colors, false);
|
|
1969
|
-
return color ? { textDecorationColor: color } : null;
|
|
1970
|
-
},
|
|
1971
|
-
"underline-offset": ({ value, isArbitrary }) => {
|
|
1972
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1973
|
-
if (isArbitrary) return { textUnderlineOffset: value };
|
|
1974
|
-
const offsets = {
|
|
1975
|
-
auto: "auto",
|
|
1976
|
-
"0": "0px",
|
|
1977
|
-
"1": "1px",
|
|
1978
|
-
"2": "2px",
|
|
1979
|
-
"4": "4px",
|
|
1980
|
-
"8": "8px"
|
|
1981
|
-
};
|
|
1982
|
-
return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
|
|
1983
|
-
},
|
|
1984
|
-
// ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
|
|
1985
|
-
// Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
|
|
1986
|
-
// the literal string 'you can see it' quotes included), so it passes straight through as a
|
|
1987
|
-
// valid `content: '*'` CSS value with no extra wrapping needed.
|
|
1988
|
-
content: ({ value, isArbitrary }) => {
|
|
1989
|
-
if (!getEffectiveIsWeb()) return null;
|
|
1990
|
-
if (isArbitrary) return { content: value };
|
|
1991
|
-
const presets = { none: "none" };
|
|
1992
|
-
return value in presets ? { content: presets[value] } : null;
|
|
1993
|
-
},
|
|
1994
|
-
// ── Arbitrary CSS property (web-only): [property:value] with no utility prefix ──
|
|
1995
|
-
// e.g. [mask-type:luminance], [--my-var:10px]. parser.ts already isolates this case
|
|
1996
|
-
// as utility: '' — it's ALSO how a stray, prefix-less negative bracket ("-[10px]",
|
|
1997
|
-
// presumably a typo) parses, which is why this only fires when the arbitrary value
|
|
1998
|
-
// itself contains a "property:value" pair; anything else (no colon) still resolves
|
|
1999
|
-
// to null exactly as before this resolver existed, rather than guessing a property.
|
|
2000
|
-
//
|
|
2001
|
-
// Only the FIRST colon splits property from value — the value itself may contain
|
|
2002
|
-
// more colons (a URL's "http://…") and must stay intact: [background:url(http://x/a.png)].
|
|
2003
|
-
// camelToKebab() in resolver.ts is a no-op on an already-kebab-case (or "--"-prefixed
|
|
2004
|
-
// custom property) key, so it can be used as the style object key as-written with no
|
|
2005
|
-
// extra case conversion — it only needs to look like a plausible CSS property name.
|
|
2006
|
-
"": ({ value, isArbitrary, negative }) => {
|
|
2007
|
-
if (!getEffectiveIsWeb() || !isArbitrary || !value) return null;
|
|
2008
|
-
if (negative) return null;
|
|
2009
|
-
const colonIdx = value.indexOf(":");
|
|
2010
|
-
if (colonIdx <= 0) return null;
|
|
2011
|
-
const prop = value.slice(0, colonIdx).trim();
|
|
2012
|
-
const cssValue = value.slice(colonIdx + 1).trim();
|
|
2013
|
-
if (!cssValue || !/^(--[\w-]+|[a-zA-Z-]+)$/.test(prop)) return null;
|
|
2014
|
-
return { [prop]: cssValue };
|
|
2015
|
-
},
|
|
2016
|
-
// ── Outline extended (web-only) ───────────────────────────────────────────
|
|
2017
|
-
outline: ({ value, isArbitrary }, { colors }) => {
|
|
2018
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2019
|
-
if (!value) return { outline: "2px solid transparent", outlineOffset: "2px" };
|
|
2020
|
-
if (value === "none") return { outline: "none", outlineOffset: "0" };
|
|
2021
|
-
if (isArbitrary) {
|
|
2022
|
-
if (/^\d/.test(value) || value.startsWith("calc(")) return { outlineWidth: value };
|
|
2023
|
-
return { outlineColor: value };
|
|
2024
|
-
}
|
|
2025
|
-
const widths = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
|
|
2026
|
-
if (value in widths) return { outlineWidth: widths[value] };
|
|
2027
|
-
const color = resolveColor(value, colors, false);
|
|
2028
|
-
return color ? { outlineColor: color } : null;
|
|
2029
|
-
},
|
|
2030
|
-
"outline-offset": ({ value, isArbitrary }) => {
|
|
2031
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2032
|
-
if (isArbitrary) return { outlineOffset: value };
|
|
2033
|
-
const offsets = { "0": "0px", "1": "1px", "2": "2px", "4": "4px", "8": "8px" };
|
|
2034
|
-
return offsets[value] ? { outlineOffset: offsets[value] } : null;
|
|
2035
|
-
},
|
|
2036
|
-
// ── Columns (web-only) ─────────────────────────────────────────────────────
|
|
2037
|
-
columns: ({ value, isArbitrary }) => {
|
|
2038
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2039
|
-
if (isArbitrary) return { columnCount: value };
|
|
2040
|
-
if (value === "auto") return { columnCount: "auto" };
|
|
2041
|
-
const n = parseInt(value, 10);
|
|
2042
|
-
if (!isNaN(n)) return { columnCount: n };
|
|
2043
|
-
const widths = {
|
|
2044
|
-
"3xs": "16rem",
|
|
2045
|
-
"2xs": "18rem",
|
|
2046
|
-
xs: "20rem",
|
|
2047
|
-
sm: "24rem",
|
|
2048
|
-
md: "28rem",
|
|
2049
|
-
lg: "32rem",
|
|
2050
|
-
xl: "36rem",
|
|
2051
|
-
"2xl": "42rem",
|
|
2052
|
-
"3xl": "48rem",
|
|
2053
|
-
"4xl": "56rem",
|
|
2054
|
-
"5xl": "64rem",
|
|
2055
|
-
"6xl": "72rem",
|
|
2056
|
-
"7xl": "80rem"
|
|
2057
|
-
};
|
|
2058
|
-
return widths[value] ? { columnWidth: widths[value] } : null;
|
|
2059
|
-
},
|
|
2060
|
-
// ── Mix / background blend mode (web-only) ───────────────────────────────
|
|
2061
|
-
"mix-blend": ({ value }) => {
|
|
2062
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2063
|
-
const modes = [
|
|
2064
|
-
"normal",
|
|
2065
|
-
"multiply",
|
|
2066
|
-
"screen",
|
|
2067
|
-
"overlay",
|
|
2068
|
-
"darken",
|
|
2069
|
-
"lighten",
|
|
2070
|
-
"color-dodge",
|
|
2071
|
-
"color-burn",
|
|
2072
|
-
"hard-light",
|
|
2073
|
-
"soft-light",
|
|
2074
|
-
"difference",
|
|
2075
|
-
"exclusion",
|
|
2076
|
-
"hue",
|
|
2077
|
-
"saturation",
|
|
2078
|
-
"color",
|
|
2079
|
-
"luminosity",
|
|
2080
|
-
"plus-lighter"
|
|
2081
|
-
];
|
|
2082
|
-
return modes.includes(value) ? { mixBlendMode: value } : null;
|
|
2083
|
-
},
|
|
2084
|
-
"bg-blend": ({ value }) => {
|
|
2085
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2086
|
-
const modes = [
|
|
2087
|
-
"normal",
|
|
2088
|
-
"multiply",
|
|
2089
|
-
"screen",
|
|
2090
|
-
"overlay",
|
|
2091
|
-
"darken",
|
|
2092
|
-
"lighten",
|
|
2093
|
-
"color-dodge",
|
|
2094
|
-
"color-burn",
|
|
2095
|
-
"hard-light",
|
|
2096
|
-
"soft-light",
|
|
2097
|
-
"difference",
|
|
2098
|
-
"exclusion",
|
|
2099
|
-
"hue",
|
|
2100
|
-
"saturation",
|
|
2101
|
-
"color",
|
|
2102
|
-
"luminosity"
|
|
2103
|
-
];
|
|
2104
|
-
return modes.includes(value) ? { backgroundBlendMode: value } : null;
|
|
2105
|
-
},
|
|
2106
|
-
// ── Will-change (web-only) ─────────────────────────────────────────────────
|
|
2107
|
-
"will-change": ({ value, isArbitrary }) => {
|
|
2108
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2109
|
-
if (isArbitrary) return { willChange: value.replace(/_/g, ", ") };
|
|
2110
|
-
const presets = {
|
|
2111
|
-
auto: "auto",
|
|
2112
|
-
scroll: "scroll-position",
|
|
2113
|
-
contents: "contents",
|
|
2114
|
-
transform: "transform"
|
|
2115
|
-
};
|
|
2116
|
-
return presets[value] ? { willChange: presets[value] } : null;
|
|
2117
|
-
},
|
|
2118
|
-
// ── Divide (child combinator CSS, web-only) ───────────────────────────────
|
|
2119
|
-
// These return special __divide* markers that resolver.ts converts to
|
|
2120
|
-
// .cls > * + * { border-... } CSS rules. No inline style is applied.
|
|
2121
|
-
"divide-x": ({ value, isArbitrary }) => {
|
|
2122
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2123
|
-
if (value === "reverse") return null;
|
|
2124
|
-
if (!value) return { __divideX: 1 };
|
|
2125
|
-
const n = parseFloat(value);
|
|
2126
|
-
return isNaN(n) ? null : { __divideX: n };
|
|
2127
|
-
},
|
|
2128
|
-
"divide-y": ({ value, isArbitrary }) => {
|
|
2129
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2130
|
-
if (value === "reverse") return null;
|
|
2131
|
-
if (!value) return { __divideY: 1 };
|
|
2132
|
-
const n = parseFloat(value);
|
|
2133
|
-
return isNaN(n) ? null : { __divideY: n };
|
|
2134
|
-
},
|
|
2135
|
-
divide: ({ value, isArbitrary }, { colors }) => {
|
|
2136
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2137
|
-
if (isArbitrary) return { __divideColor: value };
|
|
2138
|
-
const styleTokens = {
|
|
2139
|
-
solid: "solid",
|
|
2140
|
-
dashed: "dashed",
|
|
2141
|
-
dotted: "dotted",
|
|
2142
|
-
double: "double",
|
|
2143
|
-
none: "none"
|
|
2144
|
-
};
|
|
2145
|
-
if (value in styleTokens) return { __divideStyle: styleTokens[value] };
|
|
2146
|
-
const color = resolveColor(value, colors, false);
|
|
2147
|
-
return color ? { __divideColor: color } : null;
|
|
2148
|
-
},
|
|
2149
|
-
// ── Text shadow (cross-platform: iOS, Android, web) ─────────────────────
|
|
2150
|
-
// Named presets give cross-platform shadow; arbitrary is web-only.
|
|
2151
|
-
"text-shadow": ({ value, isArbitrary }, { colors }) => {
|
|
2152
|
-
if (value === "none") {
|
|
2153
|
-
return getEffectiveIsWeb() ? { textShadow: "none" } : { textShadowColor: "transparent", textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 0 };
|
|
2154
|
-
}
|
|
2155
|
-
const webPresets = {
|
|
2156
|
-
"": "0 2px 4px rgba(0,0,0,0.3)",
|
|
2157
|
-
sm: "0 1px 2px rgba(0,0,0,0.3)",
|
|
2158
|
-
md: "0 4px 6px rgba(0,0,0,0.3)",
|
|
2159
|
-
lg: "0 8px 16px rgba(0,0,0,0.5)",
|
|
2160
|
-
xl: "0 16px 32px rgba(0,0,0,0.5)"
|
|
2161
|
-
};
|
|
2162
|
-
const nativePresets = {
|
|
2163
|
-
"": { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 2 }, textShadowRadius: 4 },
|
|
2164
|
-
sm: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 2 },
|
|
2165
|
-
md: { textShadowColor: "rgba(0,0,0,0.3)", textShadowOffset: { width: 0, height: 4 }, textShadowRadius: 6 },
|
|
2166
|
-
lg: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 8 }, textShadowRadius: 16 },
|
|
2167
|
-
xl: { textShadowColor: "rgba(0,0,0,0.5)", textShadowOffset: { width: 0, height: 16 }, textShadowRadius: 32 }
|
|
2168
|
-
};
|
|
2169
|
-
if (value in webPresets) {
|
|
2170
|
-
if (getEffectiveIsWeb()) return { textShadow: webPresets[value] };
|
|
2171
|
-
return nativePresets[value] ?? null;
|
|
2172
|
-
}
|
|
2173
|
-
if (isArbitrary) {
|
|
2174
|
-
return getEffectiveIsWeb() ? { textShadow: value.replace(/_/g, " ") } : null;
|
|
2175
|
-
}
|
|
2176
|
-
const color = resolveColor(value, colors, false);
|
|
2177
|
-
if (color) {
|
|
2178
|
-
return getEffectiveIsWeb() ? { textShadow: `0 2px 4px ${color}` } : { textShadowColor: color };
|
|
2179
|
-
}
|
|
2180
|
-
return null;
|
|
2181
|
-
},
|
|
2182
|
-
// ── Perspective transform (cross-platform: iOS, Android, web) ────────────
|
|
2183
|
-
perspective: ({ value, isArbitrary }) => {
|
|
2184
|
-
if (isArbitrary) {
|
|
2185
|
-
const numPx = parseFloat(value);
|
|
2186
|
-
if (getEffectiveIsWeb()) return { transform: `perspective(${value})` };
|
|
2187
|
-
return isNaN(numPx) ? null : { transform: [{ perspective: numPx }] };
|
|
2188
|
-
}
|
|
2189
|
-
if (value === "none") return getEffectiveIsWeb() ? { transform: "none" } : null;
|
|
2190
|
-
const n = parseFloat(value);
|
|
2191
|
-
if (isNaN(n)) return null;
|
|
2192
|
-
return getEffectiveIsWeb() ? { transform: `perspective(${n}px)` } : { transform: [{ perspective: n }] };
|
|
2193
|
-
},
|
|
2194
|
-
// ── Tint color (native-only, for Image and icon components) ──────────────
|
|
2195
|
-
tint: ({ value, isArbitrary }, { colors }) => {
|
|
2196
|
-
if (getEffectiveIsWeb()) return null;
|
|
2197
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
2198
|
-
return color ? { tintColor: color } : null;
|
|
2199
|
-
},
|
|
2200
|
-
// ── Size shorthand (sets width AND height in one utility) ────────────────
|
|
2201
|
-
size: ({ value, isArbitrary }, { spacing }) => {
|
|
2202
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
2203
|
-
return v !== null ? { width: v, height: v } : null;
|
|
2204
|
-
},
|
|
2205
|
-
// ── Animations (CSS keyframe animations, web-only) ────────────────────────
|
|
2206
|
-
// Each variant injects a @keyframes rule once via the __keyframe marker.
|
|
2207
|
-
// resolver.ts detects __keyframe, injects the rule, then strips the marker
|
|
2208
|
-
// so it never reaches element inline styles.
|
|
2209
|
-
animate: ({ value, isArbitrary }, theme) => {
|
|
2210
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2211
|
-
if (isArbitrary) return buildAnimationValue(value.replace(/_/g, " "), theme.keyframes);
|
|
2212
|
-
if (value in BUILTIN_ANIMATIONS) return BUILTIN_ANIMATIONS[value];
|
|
2213
|
-
const custom = theme.animation?.[value];
|
|
2214
|
-
return custom ? buildAnimationValue(custom, theme.keyframes) : null;
|
|
2215
|
-
},
|
|
2216
|
-
// ── Line-clamp (web-only) ─────────────────────────────────────────────────
|
|
2217
|
-
"line-clamp": ({ value }) => {
|
|
2218
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2219
|
-
if (value === "none") return { overflow: "visible", display: "block", WebkitLineClamp: "unset" };
|
|
2220
|
-
const n = parseInt(value, 10);
|
|
2221
|
-
if (isNaN(n) || n < 1) return null;
|
|
2222
|
-
return {
|
|
2223
|
-
overflow: "hidden",
|
|
2224
|
-
display: "-webkit-box",
|
|
2225
|
-
WebkitBoxOrient: "vertical",
|
|
2226
|
-
WebkitLineClamp: n
|
|
2227
|
-
};
|
|
2228
|
-
},
|
|
2229
|
-
// ── Caret color (web-only) ────────────────────────────────────────────────
|
|
2230
|
-
caret: ({ value, isArbitrary }, { colors }) => {
|
|
2231
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2232
|
-
if (value === "auto" || value === "transparent") return { caretColor: value };
|
|
2233
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
2234
|
-
return color ? { caretColor: color } : null;
|
|
2235
|
-
},
|
|
2236
|
-
// ── Accent color (web-only) ───────────────────────────────────────────────
|
|
2237
|
-
accent: ({ value, isArbitrary }, { colors }) => {
|
|
2238
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2239
|
-
if (value === "auto") return { accentColor: "auto" };
|
|
2240
|
-
const color = resolveColor(value, colors, isArbitrary);
|
|
2241
|
-
return color ? { accentColor: color } : null;
|
|
2242
|
-
},
|
|
2243
|
-
// ── SVG stroke/fill (web-only) ────────────────────────────────────────────
|
|
2244
|
-
// Native is intentionally excluded: react-native-svg's <Path>/<Circle>/etc.
|
|
2245
|
-
// take stroke/fill as component PROPS, not style entries, so there's no
|
|
2246
|
-
// reliable way to apply a resolved color through the `style` prop there.
|
|
2247
|
-
// `stroke-{n}` sets strokeWidth (a plain number, unlike a color) — same
|
|
2248
|
-
// color-first-then-numeric-fallback disambiguation `border` uses above.
|
|
2249
|
-
stroke: ({ value, isArbitrary }, { colors }) => {
|
|
2250
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2251
|
-
if (!value) return null;
|
|
2252
|
-
if (value === "none") return { stroke: "none" };
|
|
2253
|
-
if (isArbitrary) {
|
|
2254
|
-
const w = toNativeValue(value);
|
|
2255
|
-
return typeof w === "number" ? { strokeWidth: w } : { stroke: value };
|
|
2256
|
-
}
|
|
2257
|
-
const color = resolveColor(value, colors, false);
|
|
2258
|
-
if (color) return { stroke: color };
|
|
2259
|
-
const n = parseFloat(value);
|
|
2260
|
-
return isNaN(n) ? null : { strokeWidth: n };
|
|
2261
|
-
},
|
|
2262
|
-
fill: ({ value, isArbitrary }, { colors }) => {
|
|
2263
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2264
|
-
if (!value) return null;
|
|
2265
|
-
if (value === "none") return { fill: "none" };
|
|
2266
|
-
if (isArbitrary) return { fill: value };
|
|
2267
|
-
const color = resolveColor(value, colors, false);
|
|
2268
|
-
return color ? { fill: color } : null;
|
|
2269
|
-
},
|
|
2270
|
-
// ── Flex ───────────────────────────────────────────────────────────────────
|
|
2271
|
-
flex: ({ value, isArbitrary }, { flex }) => {
|
|
2272
|
-
if (!value) return { display: "flex" };
|
|
2273
|
-
if (isArbitrary) {
|
|
2274
|
-
const v = parseFloat(value);
|
|
2275
|
-
return isNaN(v) ? null : { flex: v };
|
|
2276
|
-
}
|
|
2277
|
-
if (value in flex) {
|
|
2278
|
-
const v = flex[value];
|
|
2279
|
-
if (typeof v === "string" && !getEffectiveIsWeb()) {
|
|
2280
|
-
if (v === "auto" || v === "initial") return { flex: 1 };
|
|
2281
|
-
if (v === "none") return { flex: 0 };
|
|
2282
|
-
return null;
|
|
2283
|
-
}
|
|
2284
|
-
return { flex: v };
|
|
2285
|
-
}
|
|
2286
|
-
const n = parseFloat(value);
|
|
2287
|
-
return isNaN(n) ? null : { flex: n };
|
|
2288
|
-
},
|
|
2289
|
-
basis: ({ value, isArbitrary }, { spacing }) => {
|
|
2290
|
-
const v = resolveSizing(value, spacing, isArbitrary);
|
|
2291
|
-
return v !== null ? { flexBasis: v } : null;
|
|
2292
|
-
},
|
|
2293
|
-
grow: ({ value }, _) => {
|
|
2294
|
-
if (!value) return { flexGrow: 1 };
|
|
2295
|
-
const n = parseFloat(value);
|
|
2296
|
-
return { flexGrow: isNaN(n) ? 1 : n };
|
|
2297
|
-
},
|
|
2298
|
-
shrink: ({ value }, _) => {
|
|
2299
|
-
if (!value) return { flexShrink: 1 };
|
|
2300
|
-
const n = parseFloat(value);
|
|
2301
|
-
return { flexShrink: isNaN(n) ? 1 : n };
|
|
2302
|
-
},
|
|
2303
|
-
order: ({ value, negative }, _) => {
|
|
2304
|
-
const n = parseInt(value, 10);
|
|
2305
|
-
return isNaN(n) ? null : { order: negative ? -n : n };
|
|
2306
|
-
},
|
|
2307
|
-
// ── Gap ────────────────────────────────────────────────────────────────────
|
|
2308
|
-
gap: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2309
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2310
|
-
return v !== null ? { gap: v } : null;
|
|
2311
|
-
},
|
|
2312
|
-
"gap-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2313
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2314
|
-
return v !== null ? { columnGap: v } : null;
|
|
2315
|
-
},
|
|
2316
|
-
"gap-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2317
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2318
|
-
return v !== null ? { rowGap: v } : null;
|
|
2319
|
-
},
|
|
2320
|
-
// ── Position ───────────────────────────────────────────────────────────────
|
|
2321
|
-
top: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2322
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2323
|
-
return v !== null ? { top: v } : null;
|
|
2324
|
-
},
|
|
2325
|
-
right: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2326
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2327
|
-
return v !== null ? { right: v } : null;
|
|
2328
|
-
},
|
|
2329
|
-
bottom: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2330
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2331
|
-
return v !== null ? { bottom: v } : null;
|
|
2332
|
-
},
|
|
2333
|
-
left: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2334
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2335
|
-
return v !== null ? { left: v } : null;
|
|
2336
|
-
},
|
|
2337
|
-
inset: ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2338
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2339
|
-
return v !== null ? { top: v, right: v, bottom: v, left: v } : null;
|
|
2340
|
-
},
|
|
2341
|
-
"inset-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2342
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2343
|
-
return v !== null ? { left: v, right: v } : null;
|
|
2344
|
-
},
|
|
2345
|
-
"inset-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2346
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2347
|
-
return v !== null ? { top: v, bottom: v } : null;
|
|
2348
|
-
},
|
|
2349
|
-
// ── Z-index ────────────────────────────────────────────────────────────────
|
|
2350
|
-
z: ({ value, isArbitrary }, { zIndex }) => {
|
|
2351
|
-
if (isArbitrary) {
|
|
2352
|
-
const n2 = parseInt(value);
|
|
2353
|
-
return isNaN(n2) ? null : { zIndex: n2 };
|
|
2354
|
-
}
|
|
2355
|
-
const v = zIndex[value];
|
|
2356
|
-
if (v !== void 0) {
|
|
2357
|
-
if (v === "auto") return getEffectiveIsWeb() ? { zIndex: "auto" } : null;
|
|
2358
|
-
return { zIndex: v };
|
|
2359
|
-
}
|
|
2360
|
-
const n = parseInt(value);
|
|
2361
|
-
return isNaN(n) ? null : { zIndex: n };
|
|
2362
|
-
},
|
|
2363
|
-
// ── Opacity ────────────────────────────────────────────────────────────────
|
|
2364
|
-
opacity: ({ value, isArbitrary }, { opacity }) => {
|
|
2365
|
-
if (isArbitrary) {
|
|
2366
|
-
const v2 = parseFloat(value);
|
|
2367
|
-
return isNaN(v2) ? null : { opacity: v2 > 1 ? v2 / 100 : v2 };
|
|
2368
|
-
}
|
|
2369
|
-
const v = opacity[value];
|
|
2370
|
-
if (v !== void 0) return { opacity: v };
|
|
2371
|
-
const n = parseFloat(value);
|
|
2372
|
-
return isNaN(n) ? null : { opacity: n > 1 ? n / 100 : n };
|
|
2373
|
-
},
|
|
2374
|
-
// ── Font ───────────────────────────────────────────────────────────────────
|
|
2375
|
-
font: ({ value, isArbitrary }, { fontFamily, fontWeight }) => {
|
|
2376
|
-
if (isArbitrary) return { fontFamily: value };
|
|
2377
|
-
if (value in fontFamily) {
|
|
2378
|
-
const ff = fontFamily[value];
|
|
2379
|
-
return { fontFamily: Array.isArray(ff) ? ff.join(", ") : ff };
|
|
2380
|
-
}
|
|
2381
|
-
if (value in fontWeight) return { fontWeight: String(fontWeight[value]) };
|
|
2382
|
-
return null;
|
|
2383
|
-
},
|
|
2384
|
-
// ── Line height ────────────────────────────────────────────────────────────
|
|
2385
|
-
leading: ({ value, isArbitrary }, { lineHeight }) => {
|
|
2386
|
-
if (isArbitrary) return { lineHeight: getEffectiveIsWeb() ? value : toNativeValue(value) };
|
|
2387
|
-
const v = lineHeight[value];
|
|
2388
|
-
if (v === void 0) return null;
|
|
2389
|
-
if (typeof v === "string" && !getEffectiveIsWeb()) return { lineHeight: toNativeValue(v) };
|
|
2390
|
-
return { lineHeight: v };
|
|
2391
|
-
},
|
|
2392
|
-
// ── Letter spacing ─────────────────────────────────────────────────────────
|
|
2393
|
-
tracking: ({ value, isArbitrary }, { letterSpacing }) => {
|
|
2394
|
-
if (isArbitrary) return { letterSpacing: getEffectiveIsWeb() ? value : toNativeValue(value) };
|
|
2395
|
-
const v = letterSpacing[value];
|
|
2396
|
-
return v !== void 0 ? { letterSpacing: v } : null;
|
|
2397
|
-
},
|
|
2398
|
-
// ── Shadow ─────────────────────────────────────────────────────────────────
|
|
2399
|
-
shadow: ({ value }, { shadow }) => {
|
|
2400
|
-
const key = value === "" ? "DEFAULT" : value;
|
|
2401
|
-
return shadow[key] ?? null;
|
|
2402
|
-
},
|
|
2403
|
-
// ── Scale ──────────────────────────────────────────────────────────────────
|
|
2404
|
-
// Non-arbitrary: scale-150 → value='150' → 150/100 = 1.5
|
|
2405
|
-
// Arbitrary: scale-[1.5] → value='1.5' → used as-is (already the factor)
|
|
2406
|
-
scale: ({ value, isArbitrary }) => {
|
|
2407
|
-
const n = isArbitrary ? parseFloat(value) : parseFloat(value) / 100;
|
|
2408
|
-
if (isNaN(n)) return null;
|
|
2409
|
-
return getEffectiveIsWeb() ? { transform: `scale(${n})` } : { transform: [{ scale: n }] };
|
|
2410
|
-
},
|
|
2411
|
-
"scale-x": ({ value, isArbitrary }) => {
|
|
2412
|
-
const n = isArbitrary ? parseFloat(value) : parseFloat(value) / 100;
|
|
2413
|
-
if (isNaN(n)) return null;
|
|
2414
|
-
return getEffectiveIsWeb() ? { transform: `scaleX(${n})` } : { transform: [{ scaleX: n }] };
|
|
2415
|
-
},
|
|
2416
|
-
"scale-y": ({ value, isArbitrary }) => {
|
|
2417
|
-
const n = isArbitrary ? parseFloat(value) : parseFloat(value) / 100;
|
|
2418
|
-
if (isNaN(n)) return null;
|
|
2419
|
-
return getEffectiveIsWeb() ? { transform: `scaleY(${n})` } : { transform: [{ scaleY: n }] };
|
|
2420
|
-
},
|
|
2421
|
-
// ── Rotate ─────────────────────────────────────────────────────────────────
|
|
2422
|
-
rotate: ({ value, negative, isArbitrary }) => {
|
|
2423
|
-
if (isArbitrary) {
|
|
2424
|
-
const finalValue = negative ? `-${value}` : value;
|
|
2425
|
-
return getEffectiveIsWeb() ? { transform: `rotate(${finalValue})` } : { transform: [{ rotate: finalValue }] };
|
|
2426
|
-
}
|
|
2427
|
-
const deg = parseFloat(value);
|
|
2428
|
-
if (isNaN(deg)) return null;
|
|
2429
|
-
const finalDeg = negative ? -deg : deg;
|
|
2430
|
-
return getEffectiveIsWeb() ? { transform: `rotate(${finalDeg}deg)` } : { transform: [{ rotate: `${finalDeg}deg` }] };
|
|
2431
|
-
},
|
|
2432
|
-
// ── Translate ──────────────────────────────────────────────────────────────
|
|
2433
|
-
"translate-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2434
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2435
|
-
if (v === null) return null;
|
|
2436
|
-
if (getEffectiveIsWeb()) return { transform: `translateX(${typeof v === "number" ? `${v}px` : v})` };
|
|
2437
|
-
if (typeof v === "string") {
|
|
2438
|
-
const n = parseFloat(v);
|
|
2439
|
-
return isNaN(n) ? null : { transform: [{ translateX: n }] };
|
|
2440
|
-
}
|
|
2441
|
-
return { transform: [{ translateX: v }] };
|
|
2442
|
-
},
|
|
2443
|
-
"translate-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2444
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2445
|
-
if (v === null) return null;
|
|
2446
|
-
if (getEffectiveIsWeb()) return { transform: `translateY(${typeof v === "number" ? `${v}px` : v})` };
|
|
2447
|
-
if (typeof v === "string") {
|
|
2448
|
-
const n = parseFloat(v);
|
|
2449
|
-
return isNaN(n) ? null : { transform: [{ translateY: n }] };
|
|
2450
|
-
}
|
|
2451
|
-
return { transform: [{ translateY: v }] };
|
|
2452
|
-
},
|
|
2453
|
-
// ── Aspect ratio ───────────────────────────────────────────────────────────
|
|
2454
|
-
aspect: ({ value, isArbitrary }) => {
|
|
2455
|
-
if (isArbitrary) return { aspectRatio: value };
|
|
2456
|
-
const presets = { auto: "auto", square: 1, video: 16 / 9 };
|
|
2457
|
-
if (!(value in presets)) return null;
|
|
2458
|
-
const v = presets[value];
|
|
2459
|
-
if (v === "auto") return getEffectiveIsWeb() ? { aspectRatio: "auto" } : null;
|
|
2460
|
-
return { aspectRatio: v };
|
|
2461
|
-
},
|
|
2462
|
-
// ── Transition (web-only; use Animated API on native) ─────────────────────
|
|
2463
|
-
transition: ({ value }) => {
|
|
2464
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2465
|
-
const presets = {
|
|
2466
|
-
"": "color 150ms, background-color 150ms, border-color 150ms, text-decoration-color 150ms, fill 150ms, stroke 150ms, opacity 150ms, box-shadow 150ms, transform 150ms, filter 150ms, backdrop-filter 150ms",
|
|
2467
|
-
all: "all 150ms",
|
|
2468
|
-
none: "none",
|
|
2469
|
-
colors: "color 150ms, background-color 150ms, border-color 150ms",
|
|
2470
|
-
opacity: "opacity 150ms",
|
|
2471
|
-
shadow: "box-shadow 150ms",
|
|
2472
|
-
transform: "transform 150ms"
|
|
2473
|
-
};
|
|
2474
|
-
const v = presets[value];
|
|
2475
|
-
return v !== void 0 ? { transition: v } : null;
|
|
2476
|
-
},
|
|
2477
|
-
duration: ({ value, isArbitrary }) => {
|
|
2478
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2479
|
-
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
2480
|
-
const ms = isArbitrary ? value : `${value}ms`;
|
|
2481
|
-
return { transitionDuration: ms };
|
|
2482
|
-
},
|
|
2483
|
-
delay: ({ value, isArbitrary }) => {
|
|
2484
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2485
|
-
if (!isArbitrary && isNaN(parseFloat(value))) return null;
|
|
2486
|
-
const ms = isArbitrary ? value : `${value}ms`;
|
|
2487
|
-
return { transitionDelay: ms };
|
|
2488
|
-
},
|
|
2489
|
-
// ── Ring ───────────────────────────────────────────────────────────────────
|
|
2490
|
-
// Web: box-shadow outline ring (doesn't affect layout).
|
|
2491
|
-
// Native: React Native has no box-shadow, so this falls back to borderWidth/
|
|
2492
|
-
// borderColor — the closest visual approximation (used by other RN Tailwind-
|
|
2493
|
-
// likes for the same reason). Unlike the web ring, this DOES affect layout,
|
|
2494
|
-
// and it shares its properties with the `border` utility — combining
|
|
2495
|
-
// `border-*` and `ring-*` on the same native element means whichever class
|
|
2496
|
-
// comes later wins, since both ultimately set borderWidth/borderColor.
|
|
2497
|
-
ring: ({ value, isArbitrary }, { colors }) => {
|
|
2498
|
-
const onWeb = getEffectiveIsWeb();
|
|
2499
|
-
const DEFAULT_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2500
|
-
const DEFAULT_WIDTH = 3;
|
|
2501
|
-
const asNative = (w, color2) => w === 0 ? { borderWidth: 0 } : { borderWidth: w, borderColor: color2 };
|
|
2502
|
-
if (!value) {
|
|
2503
|
-
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2504
|
-
}
|
|
2505
|
-
if (value === "inset") {
|
|
2506
|
-
return onWeb ? { boxShadow: `inset 0 0 0 ${DEFAULT_WIDTH}px ${DEFAULT_COLOR}` } : asNative(DEFAULT_WIDTH, DEFAULT_COLOR);
|
|
2507
|
-
}
|
|
2508
|
-
const widthTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2509
|
-
if (!isArbitrary && value in widthTokens) {
|
|
2510
|
-
const w = widthTokens[value];
|
|
2511
|
-
return onWeb ? { boxShadow: w === 0 ? "none" : `0 0 0 ${w}px ${DEFAULT_COLOR}` } : asNative(w, DEFAULT_COLOR);
|
|
2512
|
-
}
|
|
2513
|
-
if (isArbitrary) {
|
|
2514
|
-
const numMatch = /^(\d+(?:\.\d+)?)(px|rem|em|vw|vh)?$/.exec(value);
|
|
2515
|
-
if (numMatch) {
|
|
2516
|
-
const unit = numMatch[2] ?? "px";
|
|
2517
|
-
if (onWeb) return { boxShadow: `0 0 0 ${numMatch[1]}${unit} ${DEFAULT_COLOR}` };
|
|
2518
|
-
return unit === "px" ? asNative(parseFloat(numMatch[1]), DEFAULT_COLOR) : null;
|
|
2519
|
-
}
|
|
2520
|
-
return onWeb ? { boxShadow: value.replace(/_/g, " ") } : null;
|
|
2521
|
-
}
|
|
2522
|
-
const color = resolveColor(value, colors, false);
|
|
2523
|
-
if (color) {
|
|
2524
|
-
return onWeb ? { boxShadow: `0 0 0 ${DEFAULT_WIDTH}px ${color}` } : asNative(DEFAULT_WIDTH, color);
|
|
2525
|
-
}
|
|
2526
|
-
return null;
|
|
2527
|
-
},
|
|
2528
|
-
// Web-only, unlike `ring` above: this stacks a second box-shadow layer to
|
|
2529
|
-
// create a gap between the element and the ring. There's no native
|
|
2530
|
-
// equivalent to approximate that with (a border can't create a gap outside
|
|
2531
|
-
// its own element without an extra wrapper view), so this stays a no-op
|
|
2532
|
-
// on native rather than rendering a misleading half-translation.
|
|
2533
|
-
"ring-offset": ({ value, isArbitrary }, _theme) => {
|
|
2534
|
-
if (!getEffectiveIsWeb()) return null;
|
|
2535
|
-
const DEFAULT_RING_COLOR = "rgba(59, 130, 246, 0.5)";
|
|
2536
|
-
const DEFAULT_RING_WIDTH = 3;
|
|
2537
|
-
const offsetTokens = { "0": 0, "1": 1, "2": 2, "4": 4, "8": 8 };
|
|
2538
|
-
let offsetWidth;
|
|
2539
|
-
if (!isArbitrary) {
|
|
2540
|
-
offsetWidth = value in offsetTokens ? offsetTokens[value] : null;
|
|
2541
|
-
} else {
|
|
2542
|
-
offsetWidth = /^-?\d+(\.\d+)?$/.test(value) ? parseFloat(value) : value;
|
|
2543
|
-
}
|
|
2544
|
-
if (offsetWidth === null || typeof offsetWidth === "number" && isNaN(offsetWidth)) return null;
|
|
2545
|
-
const isZero = offsetWidth === 0 || offsetWidth === "0";
|
|
2546
|
-
const offsetCss = typeof offsetWidth === "number" ? `${offsetWidth}px` : offsetWidth;
|
|
2547
|
-
return {
|
|
2548
|
-
boxShadow: isZero ? `0 0 0 ${DEFAULT_RING_WIDTH}px ${DEFAULT_RING_COLOR}` : `0 0 0 ${offsetCss} #fff, 0 0 0 calc(${offsetCss} + ${DEFAULT_RING_WIDTH}px) ${DEFAULT_RING_COLOR}`
|
|
2549
|
-
};
|
|
2550
|
-
},
|
|
2551
|
-
// ── Space between ─────────────────────────────────────────────────────────
|
|
2552
|
-
// On web: emits __spaceX/__spaceY markers → resolver generates > * + * CSS rules.
|
|
2553
|
-
// On native (RN 0.71+): uses columnGap/rowGap directly.
|
|
2554
|
-
"space-x": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2555
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2556
|
-
if (v === null) return null;
|
|
2557
|
-
if (getEffectiveIsWeb()) return { __spaceX: v };
|
|
2558
|
-
return { columnGap: v };
|
|
2559
|
-
},
|
|
2560
|
-
"space-y": ({ value, negative, isArbitrary }, { spacing }) => {
|
|
2561
|
-
const v = resolveSpacing(value, negative, spacing, isArbitrary);
|
|
2562
|
-
if (v === null) return null;
|
|
2563
|
-
if (getEffectiveIsWeb()) return { __spaceY: v };
|
|
2564
|
-
return { rowGap: v };
|
|
2565
|
-
}
|
|
2566
|
-
};
|
|
2567
|
-
for (const [utility, prop] of Object.entries(PADDING_MARGIN_PROPS)) {
|
|
2568
|
-
RESOLVERS[utility] = makeSpacingResolver(prop);
|
|
2569
|
-
}
|
|
2570
|
-
for (const [utility, [widthProp, colorProp]] of Object.entries(BORDER_SIDE_PROPS)) {
|
|
2571
|
-
RESOLVERS[utility] = makeBorderSideResolver(widthProp, colorProp);
|
|
2572
|
-
}
|
|
2573
|
-
var NAMED_GROUP_PEER_MARKER_RE = /^(group|peer)\/.+$/;
|
|
2574
|
-
function resolveUtility(parsed, theme) {
|
|
2575
|
-
if (!parsed.value) {
|
|
2576
|
-
if (parsed.utility in PLUGIN_STANDALONE) return PLUGIN_STANDALONE[parsed.utility] ?? null;
|
|
2577
|
-
if (parsed.utility in getStandalone()) return getStandalone()[parsed.utility] ?? null;
|
|
2578
|
-
if (NAMED_GROUP_PEER_MARKER_RE.test(parsed.utility)) return getEffectiveIsWeb() ? {} : null;
|
|
2579
|
-
}
|
|
2580
|
-
const resolver = PLUGIN_RESOLVERS[parsed.utility] ?? RESOLVERS[parsed.utility];
|
|
2581
|
-
if (resolver) return resolver(parsed, theme);
|
|
2582
|
-
return null;
|
|
2583
|
-
}
|
|
2584
|
-
var PLUGIN_STANDALONE = {};
|
|
2585
|
-
var PLUGIN_RESOLVERS = {};
|
|
2586
|
-
function clearPluginUtilities() {
|
|
2587
|
-
for (const key of Object.keys(PLUGIN_STANDALONE)) delete PLUGIN_STANDALONE[key];
|
|
2588
|
-
for (const key of Object.keys(PLUGIN_RESOLVERS)) delete PLUGIN_RESOLVERS[key];
|
|
2589
|
-
_sortedPrefixes = null;
|
|
2590
|
-
_standaloneNames = null;
|
|
2591
|
-
}
|
|
2592
|
-
function getPluginStandaloneMap() {
|
|
2593
|
-
return PLUGIN_STANDALONE;
|
|
2594
|
-
}
|
|
2595
|
-
function isKnownUtility(utility) {
|
|
2596
|
-
return utility in getStandalone() || utility in RESOLVERS || utility in PLUGIN_STANDALONE || utility in PLUGIN_RESOLVERS || NAMED_GROUP_PEER_MARKER_RE.test(utility);
|
|
2597
|
-
}
|
|
2598
|
-
var _sortedPrefixes = null;
|
|
2599
|
-
var _standaloneNames = null;
|
|
2600
|
-
function getBuiltinUtilityPrefixes() {
|
|
2601
|
-
if (!_sortedPrefixes) {
|
|
2602
|
-
const all = [.../* @__PURE__ */ new Set([...Object.keys(RESOLVERS), ...Object.keys(PLUGIN_RESOLVERS)])];
|
|
2603
|
-
_sortedPrefixes = all.sort((a, b) => b.length - a.length);
|
|
2604
|
-
}
|
|
2605
|
-
return _sortedPrefixes;
|
|
2606
|
-
}
|
|
2607
|
-
function getBuiltinStandaloneNames() {
|
|
2608
|
-
if (!_standaloneNames) {
|
|
2609
|
-
_standaloneNames = /* @__PURE__ */ new Set([...Object.keys(getStandalone()), ...Object.keys(PLUGIN_STANDALONE)]);
|
|
2610
|
-
}
|
|
2611
|
-
return _standaloneNames;
|
|
2612
|
-
}
|
|
2613
|
-
|
|
2614
|
-
// src/core/parser.ts
|
|
2615
|
-
var UNSAFE_ARBITRARY_VALUE = /[{};\\]|\/\*|\*\//;
|
|
2616
|
-
function isSafeArbitraryValue(value) {
|
|
2617
|
-
if (!UNSAFE_ARBITRARY_VALUE.test(value)) return true;
|
|
2618
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2619
|
-
kbachWarn(`Unsafe arbitrary value rejected: "${value}"`);
|
|
2620
|
-
}
|
|
2621
|
-
return false;
|
|
2622
|
-
}
|
|
2623
|
-
function parseClass(className) {
|
|
2624
|
-
const trimmed = className.trim();
|
|
2625
|
-
if (!trimmed) return null;
|
|
2626
|
-
const modifiers = [];
|
|
2627
|
-
let remaining = trimmed;
|
|
2628
|
-
while (true) {
|
|
2629
|
-
const colonIdx = findOuterColon(remaining);
|
|
2630
|
-
if (colonIdx === -1) break;
|
|
2631
|
-
const candidate = remaining.slice(0, colonIdx);
|
|
2632
|
-
if (!isKnownModifier(candidate)) break;
|
|
2633
|
-
modifiers.push(candidate);
|
|
2634
|
-
remaining = remaining.slice(colonIdx + 1);
|
|
2635
|
-
}
|
|
2636
|
-
let important = false;
|
|
2637
|
-
if (remaining.startsWith("!") && remaining.length > 1) {
|
|
2638
|
-
important = true;
|
|
2639
|
-
remaining = remaining.slice(1);
|
|
2640
|
-
}
|
|
2641
|
-
let negative = false;
|
|
2642
|
-
if (remaining.startsWith("-") && remaining.length > 1 && remaining[1] !== "-") {
|
|
2643
|
-
negative = true;
|
|
2644
|
-
remaining = remaining.slice(1);
|
|
2645
|
-
}
|
|
2646
|
-
let bracketDepth = 0;
|
|
2647
|
-
let bracketStart = -1;
|
|
2648
|
-
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
2649
|
-
if (remaining[i] === "]") bracketDepth++;
|
|
2650
|
-
else if (remaining[i] === "[") {
|
|
2651
|
-
bracketDepth--;
|
|
2652
|
-
if (bracketDepth === 0) {
|
|
2653
|
-
bracketStart = i;
|
|
2654
|
-
break;
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
if (bracketStart > 0 && remaining[bracketStart - 1] === "-" && remaining.endsWith("]")) {
|
|
2659
|
-
const utility = remaining.slice(0, bracketStart - 1);
|
|
2660
|
-
const value = remaining.slice(bracketStart + 1, -1).replace(/_/g, " ");
|
|
2661
|
-
if (!isSafeArbitraryValue(value)) return null;
|
|
2662
|
-
return { original: trimmed, modifiers, negative, important, utility, value, isArbitrary: true };
|
|
2663
|
-
}
|
|
2664
|
-
if (remaining.endsWith("]") && bracketStart === -1) {
|
|
2665
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2666
|
-
kbachWarn(`Unbalanced brackets: "${trimmed}"`);
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
if (remaining.startsWith("[") && remaining.endsWith("]")) {
|
|
2670
|
-
const value = remaining.slice(1, -1).replace(/_/g, " ");
|
|
2671
|
-
if (!isSafeArbitraryValue(value)) return null;
|
|
2672
|
-
return { original: trimmed, modifiers, negative, important, utility: "", value, isArbitrary: true };
|
|
2673
|
-
}
|
|
2674
|
-
if (getBuiltinStandaloneNames().has(remaining)) {
|
|
2675
|
-
return { original: trimmed, modifiers, negative, important, utility: remaining, value: "", isArbitrary: false };
|
|
2676
|
-
}
|
|
2677
|
-
for (const prefix of getBuiltinUtilityPrefixes()) {
|
|
2678
|
-
if (remaining === prefix) {
|
|
2679
|
-
return { original: trimmed, modifiers, negative, important, utility: prefix, value: "", isArbitrary: false };
|
|
2680
|
-
}
|
|
2681
|
-
if (remaining.startsWith(prefix + "-")) {
|
|
2682
|
-
const value = remaining.slice(prefix.length + 1);
|
|
2683
|
-
return { original: trimmed, modifiers, negative, important, utility: prefix, value, isArbitrary: false };
|
|
2684
|
-
}
|
|
2685
|
-
}
|
|
2686
|
-
const firstDash = remaining.indexOf("-");
|
|
2687
|
-
if (firstDash > 0) {
|
|
2688
|
-
return {
|
|
2689
|
-
original: trimmed,
|
|
2690
|
-
modifiers,
|
|
2691
|
-
negative,
|
|
2692
|
-
important,
|
|
2693
|
-
utility: remaining.slice(0, firstDash),
|
|
2694
|
-
value: remaining.slice(firstDash + 1),
|
|
2695
|
-
isArbitrary: false
|
|
2696
|
-
};
|
|
2697
|
-
}
|
|
2698
|
-
return { original: trimmed, modifiers, negative, important, utility: remaining, value: "", isArbitrary: false };
|
|
2699
|
-
}
|
|
2700
|
-
function splitClassTokens(classString) {
|
|
2701
|
-
const tokens = [];
|
|
2702
|
-
let current = "";
|
|
2703
|
-
let depth = 0;
|
|
2704
|
-
let parenDepth = 0;
|
|
2705
|
-
for (let i = 0; i < classString.length; i++) {
|
|
2706
|
-
const ch = classString[i];
|
|
2707
|
-
if (ch === "[") {
|
|
2708
|
-
depth++;
|
|
2709
|
-
current += ch;
|
|
2710
|
-
continue;
|
|
2711
|
-
}
|
|
2712
|
-
if (ch === "]") {
|
|
2713
|
-
depth--;
|
|
2714
|
-
current += ch;
|
|
2715
|
-
continue;
|
|
2716
|
-
}
|
|
2717
|
-
if (ch === "(") {
|
|
2718
|
-
parenDepth++;
|
|
2719
|
-
current += ch;
|
|
2720
|
-
continue;
|
|
2721
|
-
}
|
|
2722
|
-
if (ch === ")") {
|
|
2723
|
-
parenDepth--;
|
|
2724
|
-
current += ch;
|
|
2725
|
-
continue;
|
|
2726
|
-
}
|
|
2727
|
-
if (/\s/.test(ch)) {
|
|
2728
|
-
if (depth === 0 && parenDepth === 0) {
|
|
2729
|
-
if (current) {
|
|
2730
|
-
tokens.push(current);
|
|
2731
|
-
current = "";
|
|
2732
|
-
}
|
|
2733
|
-
}
|
|
2734
|
-
} else {
|
|
2735
|
-
current += ch;
|
|
2736
|
-
}
|
|
2737
|
-
}
|
|
2738
|
-
if (current) tokens.push(current);
|
|
2739
|
-
return tokens;
|
|
2740
|
-
}
|
|
2741
|
-
function normalizeClassString(classString) {
|
|
2742
|
-
return splitClassTokens(classString).join(" ");
|
|
2743
|
-
}
|
|
2744
|
-
function parseClasses(classString) {
|
|
2745
|
-
const results = [];
|
|
2746
|
-
for (const token of splitClassTokens(classString)) {
|
|
2747
|
-
const parsed = parseClass(token);
|
|
2748
|
-
if (parsed) results.push(parsed);
|
|
2749
|
-
}
|
|
2750
|
-
return results;
|
|
2751
|
-
}
|
|
2752
|
-
function findOuterColon(s) {
|
|
2753
|
-
let depth = 0;
|
|
2754
|
-
for (let i = 0; i < s.length; i++) {
|
|
2755
|
-
const ch = s[i];
|
|
2756
|
-
if (ch === "[") depth++;
|
|
2757
|
-
else if (ch === "]") depth--;
|
|
2758
|
-
else if (ch === ":" && depth === 0) return i;
|
|
2759
|
-
}
|
|
2760
|
-
return -1;
|
|
2761
|
-
}
|
|
2762
|
-
|
|
2763
|
-
// src/core/responsiveStore.ts
|
|
2764
|
-
var RESPONSIVE_KEY = "__kbach_responsive__";
|
|
2765
|
-
function getStore() {
|
|
2766
|
-
const g = globalThis;
|
|
2767
|
-
if (!g[RESPONSIVE_KEY]) {
|
|
2768
|
-
g[RESPONSIVE_KEY] = { width: 0, notifiedWidth: 0, screens: {}, listeners: /* @__PURE__ */ new Set() };
|
|
2769
|
-
}
|
|
2770
|
-
return g[RESPONSIVE_KEY];
|
|
2771
|
-
}
|
|
2772
|
-
function syncGlobalWidth(width) {
|
|
2773
|
-
getStore().width = width;
|
|
2774
|
-
}
|
|
2775
|
-
function syncGlobalScreens(screens) {
|
|
2776
|
-
getStore().screens = screens;
|
|
2777
|
-
}
|
|
2778
|
-
function getGlobalScreens() {
|
|
2779
|
-
return getStore().screens;
|
|
2780
|
-
}
|
|
2781
|
-
function setGlobalWidth(width) {
|
|
2782
|
-
const store = getStore();
|
|
2783
|
-
store.width = width;
|
|
2784
|
-
if (store.notifiedWidth === width) return;
|
|
2785
|
-
store.notifiedWidth = width;
|
|
2786
|
-
for (const l of store.listeners) l();
|
|
2787
|
-
}
|
|
2788
|
-
function getGlobalWidth() {
|
|
2789
|
-
return getStore().width;
|
|
2790
|
-
}
|
|
2791
|
-
function subscribeGlobalWidth(listener) {
|
|
2792
|
-
const store = getStore();
|
|
2793
|
-
store.listeners.add(listener);
|
|
2794
|
-
return () => store.listeners.delete(listener);
|
|
2795
|
-
}
|
|
2796
|
-
function getActiveBreakpoints(width) {
|
|
2797
|
-
const store = getStore();
|
|
2798
|
-
const w = width ?? store.width;
|
|
2799
|
-
const active = /* @__PURE__ */ new Set();
|
|
2800
|
-
for (const [name, minW] of Object.entries(store.screens)) {
|
|
2801
|
-
if (typeof minW === "number" && w >= minW) active.add(name);
|
|
2802
|
-
}
|
|
2803
|
-
return active;
|
|
2804
|
-
}
|
|
2805
|
-
|
|
2806
|
-
// src/core/resolver.ts
|
|
2807
|
-
var _themeCache = /* @__PURE__ */ new WeakMap();
|
|
2808
|
-
function getThemeCache(theme) {
|
|
2809
|
-
let cache = _themeCache.get(theme);
|
|
2810
|
-
if (!cache) {
|
|
2811
|
-
cache = new LRUCache(1e4);
|
|
2812
|
-
_themeCache.set(theme, cache);
|
|
2813
|
-
}
|
|
2814
|
-
return cache;
|
|
2815
|
-
}
|
|
2816
|
-
var _sortCache = /* @__PURE__ */ new WeakMap();
|
|
2817
|
-
function getSortedEntries(resolved) {
|
|
2818
|
-
let sorted = _sortCache.get(resolved);
|
|
2819
|
-
if (!sorted) {
|
|
2820
|
-
const entries = Object.entries(resolved);
|
|
2821
|
-
entries.sort((a, b) => {
|
|
2822
|
-
const pa = a[0] === "base" ? -1 : a[0].split(":").length;
|
|
2823
|
-
const pb = b[0] === "base" ? -1 : b[0].split(":").length;
|
|
2824
|
-
return pa - pb;
|
|
2825
|
-
});
|
|
2826
|
-
sorted = entries;
|
|
2827
|
-
_sortCache.set(resolved, sorted);
|
|
2828
|
-
}
|
|
2829
|
-
return sorted;
|
|
2830
|
-
}
|
|
2831
|
-
var FONT_KEY = "__kbach_default_font__";
|
|
2832
|
-
function setDefaultFontFamily(font) {
|
|
2833
|
-
globalThis[FONT_KEY] = font;
|
|
2834
|
-
}
|
|
2835
|
-
function getDefaultFontFamily() {
|
|
2836
|
-
return globalThis[FONT_KEY];
|
|
2837
|
-
}
|
|
2838
|
-
var _styleEl = null;
|
|
2839
|
-
var _ruleIndexByKey = /* @__PURE__ */ new Map();
|
|
2840
|
-
function evictInjectedRule(rule) {
|
|
2841
|
-
const idx = _ruleIndexByKey.get(rule);
|
|
2842
|
-
_ruleIndexByKey.delete(rule);
|
|
2843
|
-
if (idx === void 0) return;
|
|
2844
|
-
const sheet = _styleEl?.sheet;
|
|
2845
|
-
if (!sheet) return;
|
|
2846
|
-
try {
|
|
2847
|
-
sheet.deleteRule(idx);
|
|
2848
|
-
} catch {
|
|
2849
|
-
return;
|
|
2850
|
-
}
|
|
2851
|
-
for (const [key, i] of _ruleIndexByKey) {
|
|
2852
|
-
if (i > idx) _ruleIndexByKey.set(key, i - 1);
|
|
2853
|
-
}
|
|
2854
|
-
}
|
|
2855
|
-
var _injectedRules = new LRUCache(5e4, evictInjectedRule);
|
|
2856
|
-
var _CSS_DISABLED_KEY = "__kbach_runtime_css_disabled__";
|
|
2857
|
-
function disableRuntimeCSS() {
|
|
2858
|
-
globalThis[_CSS_DISABLED_KEY] = true;
|
|
2859
|
-
}
|
|
2860
|
-
function isRuntimeCSSDisabled() {
|
|
2861
|
-
return !!globalThis[_CSS_DISABLED_KEY];
|
|
2862
|
-
}
|
|
2863
|
-
function getStyleEl() {
|
|
2864
|
-
if (_styleEl) return _styleEl;
|
|
2865
|
-
_styleEl = document.createElement("style");
|
|
2866
|
-
_styleEl.setAttribute("data-kbach", "");
|
|
2867
|
-
document.head.appendChild(_styleEl);
|
|
2868
|
-
return _styleEl;
|
|
2869
|
-
}
|
|
2870
|
-
function injectRule(rule) {
|
|
2871
|
-
if (isRuntimeCSSDisabled()) return;
|
|
2872
|
-
if (_injectedRules.get(rule)) return;
|
|
2873
|
-
try {
|
|
2874
|
-
const sheet = getStyleEl().sheet;
|
|
2875
|
-
if (sheet) {
|
|
2876
|
-
const idx = sheet.cssRules.length;
|
|
2877
|
-
sheet.insertRule(rule, idx);
|
|
2878
|
-
_ruleIndexByKey.set(rule, idx);
|
|
2879
|
-
_injectedRules.set(rule, true);
|
|
2880
|
-
}
|
|
2881
|
-
} catch {
|
|
2882
|
-
}
|
|
2883
|
-
}
|
|
2884
|
-
var _globalStyleEl = null;
|
|
2885
|
-
function getGlobalStyleEl() {
|
|
2886
|
-
if (_globalStyleEl) return _globalStyleEl;
|
|
2887
|
-
_globalStyleEl = document.createElement("style");
|
|
2888
|
-
_globalStyleEl.setAttribute("data-kbach-global", "");
|
|
2889
|
-
document.head.insertBefore(_globalStyleEl, getStyleEl());
|
|
2890
|
-
return _globalStyleEl;
|
|
2891
|
-
}
|
|
2892
|
-
function injectGlobalStyles(theme) {
|
|
2893
|
-
if (typeof document === "undefined" || isRuntimeCSSDisabled()) return;
|
|
2894
|
-
const rules = document.getElementById(RESET_STYLE_ID) ? [] : [BASE_RESET];
|
|
2895
|
-
const ff = theme.fontFamily;
|
|
2896
|
-
if (ff?.sans && ff.sans !== "System") {
|
|
2897
|
-
const family = Array.isArray(ff.sans) ? ff.sans.join(", ") : ff.sans;
|
|
2898
|
-
rules.push(`body { font-family: ${family}; }`);
|
|
2899
|
-
}
|
|
2900
|
-
getGlobalStyleEl().textContent = rules.join("\n");
|
|
2901
|
-
}
|
|
2902
|
-
function buildDivideDecls(styles, forceImportant) {
|
|
2903
|
-
const imp = forceImportant ? " !important" : "";
|
|
2904
|
-
const parts = [];
|
|
2905
|
-
if ("__divideX" in styles) {
|
|
2906
|
-
const w = Number(styles.__divideX);
|
|
2907
|
-
parts.push(`border-left-width: ${w}px${imp}`, `border-right-width: 0px${imp}`);
|
|
2908
|
-
}
|
|
2909
|
-
if ("__divideY" in styles) {
|
|
2910
|
-
const w = Number(styles.__divideY);
|
|
2911
|
-
parts.push(`border-top-width: ${w}px${imp}`, `border-bottom-width: 0px${imp}`);
|
|
2912
|
-
}
|
|
2913
|
-
if ("__divideColor" in styles) parts.push(`border-color: ${String(styles.__divideColor)}${imp}`);
|
|
2914
|
-
if ("__divideStyle" in styles) parts.push(`border-style: ${String(styles.__divideStyle)}${imp}`);
|
|
2915
|
-
return parts.join("; ");
|
|
2916
|
-
}
|
|
2917
|
-
function buildSpaceDecls(styles, forceImportant) {
|
|
2918
|
-
const imp = forceImportant ? " !important" : "";
|
|
2919
|
-
const parts = [];
|
|
2920
|
-
if ("__spaceX" in styles) {
|
|
2921
|
-
const v = styles.__spaceX;
|
|
2922
|
-
const val = typeof v === "number" ? `${v}px` : String(v);
|
|
2923
|
-
parts.push(`margin-left: ${val}${imp}`);
|
|
2924
|
-
}
|
|
2925
|
-
if ("__spaceY" in styles) {
|
|
2926
|
-
const v = styles.__spaceY;
|
|
2927
|
-
const val = typeof v === "number" ? `${v}px` : String(v);
|
|
2928
|
-
parts.push(`margin-top: ${val}${imp}`);
|
|
2929
|
-
}
|
|
2930
|
-
return parts.join("; ");
|
|
2931
|
-
}
|
|
2932
|
-
var RN_ONLY_PROPS = /* @__PURE__ */ new Set([
|
|
2933
|
-
"shadowColor",
|
|
2934
|
-
"shadowOffset",
|
|
2935
|
-
"shadowOpacity",
|
|
2936
|
-
"shadowRadius",
|
|
2937
|
-
"elevation",
|
|
2938
|
-
"includeFontPadding",
|
|
2939
|
-
"textAlignVertical",
|
|
2940
|
-
"writingDirection",
|
|
2941
|
-
"textShadowColor",
|
|
2942
|
-
"textShadowOffset",
|
|
2943
|
-
"textShadowRadius",
|
|
2944
|
-
"tintColor",
|
|
2945
|
-
"__divideX",
|
|
2946
|
-
"__divideY",
|
|
2947
|
-
"__divideColor",
|
|
2948
|
-
"__divideStyle",
|
|
2949
|
-
"__keyframe",
|
|
2950
|
-
"__spaceX",
|
|
2951
|
-
"__spaceY"
|
|
2952
|
-
]);
|
|
2953
|
-
var CSS_UNITLESS = /* @__PURE__ */ new Set([
|
|
2954
|
-
"opacity",
|
|
2955
|
-
"fontWeight",
|
|
2956
|
-
"flex",
|
|
2957
|
-
"flexGrow",
|
|
2958
|
-
"flexShrink",
|
|
2959
|
-
"order",
|
|
2960
|
-
"zIndex",
|
|
2961
|
-
"aspectRatio",
|
|
2962
|
-
"columnCount",
|
|
2963
|
-
"lineHeight",
|
|
2964
|
-
"gridColumnStart",
|
|
2965
|
-
"gridColumnEnd",
|
|
2966
|
-
"gridRowStart",
|
|
2967
|
-
"gridRowEnd"
|
|
2968
|
-
]);
|
|
2969
|
-
var RN_SHORTHAND_EXPAND = {
|
|
2970
|
-
marginHorizontal: ["margin-left", "margin-right"],
|
|
2971
|
-
marginVertical: ["margin-top", "margin-bottom"],
|
|
2972
|
-
paddingHorizontal: ["padding-left", "padding-right"],
|
|
2973
|
-
paddingVertical: ["padding-top", "padding-bottom"]
|
|
2974
|
-
};
|
|
2975
|
-
function styleValueToCSS(styles, forceImportant = false) {
|
|
2976
|
-
const parts = [];
|
|
2977
|
-
for (const [prop, val] of Object.entries(styles)) {
|
|
2978
|
-
if (val === void 0 || val === null || typeof val === "object" || RN_ONLY_PROPS.has(prop)) continue;
|
|
2979
|
-
let cssVal;
|
|
2980
|
-
if (typeof val === "number") {
|
|
2981
|
-
const isCustomProp = prop.startsWith("--");
|
|
2982
|
-
cssVal = val === 0 || isCustomProp || CSS_UNITLESS.has(prop) ? String(val) : `${val}px`;
|
|
2983
|
-
} else {
|
|
2984
|
-
cssVal = String(val);
|
|
2985
|
-
}
|
|
2986
|
-
const imp = forceImportant || prop === "display" && (cssVal === "grid" || cssVal === "inline-grid") || prop === "position" && (cssVal === "sticky" || cssVal === "fixed" || cssVal === "static") ? " !important" : "";
|
|
2987
|
-
if (prop in RN_SHORTHAND_EXPAND) {
|
|
2988
|
-
const [p1, p2] = RN_SHORTHAND_EXPAND[prop];
|
|
2989
|
-
parts.push(`${p1}: ${cssVal}${imp}`, `${p2}: ${cssVal}${imp}`);
|
|
2990
|
-
continue;
|
|
2991
|
-
}
|
|
2992
|
-
parts.push(`${camelToKebab(prop)}: ${cssVal}${imp}`);
|
|
2993
|
-
}
|
|
2994
|
-
return parts.join("; ");
|
|
2995
|
-
}
|
|
2996
|
-
function camelToKebab(str) {
|
|
2997
|
-
return str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
2998
|
-
}
|
|
2999
|
-
function buildClassCSSRules(cls, bucketKey, styles, darkMode, important, screens) {
|
|
3000
|
-
const rules = [];
|
|
3001
|
-
if ("__keyframe" in styles && typeof styles.__keyframe === "string") {
|
|
3002
|
-
rules.push(styles.__keyframe);
|
|
3003
|
-
}
|
|
3004
|
-
const isDivide = "__divideX" in styles || "__divideY" in styles || "__divideColor" in styles || "__divideStyle" in styles;
|
|
3005
|
-
const isSpace = "__spaceX" in styles || "__spaceY" in styles;
|
|
3006
|
-
const isChildCombinator = isDivide || isSpace;
|
|
3007
|
-
const escaped = escapeCSSSelector(cls);
|
|
3008
|
-
const childSuffix = isChildCombinator ? " > * + *" : "";
|
|
3009
|
-
if (bucketKey === "base") {
|
|
3010
|
-
const decls2 = isDivide ? buildDivideDecls(styles, important) : isSpace ? buildSpaceDecls(styles, important) : styleValueToCSS(styles, important);
|
|
3011
|
-
if (!decls2) return rules;
|
|
3012
|
-
rules.push(`.${escaped}${childSuffix} { ${decls2} }`);
|
|
3013
|
-
return rules;
|
|
3014
|
-
}
|
|
3015
|
-
const mods = bucketKey.split(":");
|
|
3016
|
-
let darkScheme;
|
|
3017
|
-
let needsImportant = important;
|
|
3018
|
-
const pseudoParts = [];
|
|
3019
|
-
const ancestorParts = [];
|
|
3020
|
-
const dirParts = [];
|
|
3021
|
-
const mediaWrappers = [];
|
|
3022
|
-
let minWidth = 0;
|
|
3023
|
-
for (const mod of mods) {
|
|
3024
|
-
const def = getModifier(mod);
|
|
3025
|
-
if (!def) continue;
|
|
3026
|
-
if (def.darkScheme) darkScheme = def.darkScheme;
|
|
3027
|
-
if (def.pseudo) pseudoParts.push(def.pseudo);
|
|
3028
|
-
if (def.ancestorSelector) {
|
|
3029
|
-
ancestorParts.push(def.ancestorSelector);
|
|
3030
|
-
needsImportant = true;
|
|
3031
|
-
}
|
|
3032
|
-
if (def.dirSelector) {
|
|
3033
|
-
dirParts.push(def.dirSelector);
|
|
3034
|
-
needsImportant = true;
|
|
3035
|
-
}
|
|
3036
|
-
if (def.mediaQuery) {
|
|
3037
|
-
mediaWrappers.push(`@media ${def.mediaQuery}`);
|
|
3038
|
-
needsImportant = true;
|
|
3039
|
-
}
|
|
3040
|
-
if (def.isResponsive) {
|
|
3041
|
-
const w = screens[mod] ?? 0;
|
|
3042
|
-
if (w > minWidth) minWidth = w;
|
|
3043
|
-
}
|
|
3044
|
-
if (def.forcesImportant) needsImportant = true;
|
|
3045
|
-
}
|
|
3046
|
-
const pseudoSuffix = pseudoParts.join("");
|
|
3047
|
-
const elementSelector = `.${escaped}${pseudoSuffix}${childSuffix}`;
|
|
3048
|
-
const ancestorPrefix = ancestorParts.join("");
|
|
3049
|
-
const dirPrefix = dirParts.join("");
|
|
3050
|
-
const selector = `${dirPrefix}${ancestorPrefix}${elementSelector}`;
|
|
3051
|
-
const decls = isDivide ? buildDivideDecls(styles, needsImportant) : isSpace ? buildSpaceDecls(styles, needsImportant) : styleValueToCSS(styles, needsImportant);
|
|
3052
|
-
if (!decls) return rules;
|
|
3053
|
-
let rule;
|
|
3054
|
-
if (darkScheme === "dark") {
|
|
3055
|
-
if (darkMode === "media") rule = `@media (prefers-color-scheme: dark) { ${selector} { ${decls} } }`;
|
|
3056
|
-
else if (darkMode === "class") rule = `.dark ${selector} { ${decls} }`;
|
|
3057
|
-
else rule = `[data-theme="dark"] ${selector} { ${decls} }`;
|
|
3058
|
-
} else if (darkScheme === "light") {
|
|
3059
|
-
if (darkMode === "media") rule = `@media (prefers-color-scheme: light) { ${selector} { ${decls} } }`;
|
|
3060
|
-
else if (darkMode === "class") rule = `.light ${selector} { ${decls} }`;
|
|
3061
|
-
else rule = `[data-theme="light"] ${selector} { ${decls} }`;
|
|
3062
|
-
} else {
|
|
3063
|
-
rule = `${selector} { ${decls} }`;
|
|
3064
|
-
}
|
|
3065
|
-
for (const mw of mediaWrappers) rule = `${mw} { ${rule} }`;
|
|
3066
|
-
if (minWidth > 0) rule = `@media (min-width: ${minWidth}px) { ${rule} }`;
|
|
3067
|
-
rules.push(rule);
|
|
3068
|
-
return rules;
|
|
3069
|
-
}
|
|
3070
|
-
function injectClassRule(cls, bucketKey, styles, darkMode, important) {
|
|
3071
|
-
const cssRules = buildClassCSSRules(cls, bucketKey, styles, darkMode, important, getGlobalScreens());
|
|
3072
|
-
for (const r of cssRules) injectRule(r);
|
|
3073
|
-
}
|
|
3074
|
-
function resolve(classString, theme, darkMode = "attribute") {
|
|
3075
|
-
const cache = getThemeCache(theme);
|
|
3076
|
-
const cacheKey = `${classString}::${darkMode}`;
|
|
3077
|
-
const cached = cache.get(cacheKey);
|
|
3078
|
-
if (cached) return cached;
|
|
3079
|
-
const result = {};
|
|
3080
|
-
const onWeb = isWeb;
|
|
3081
|
-
for (const parsed of parseClasses(classString)) {
|
|
3082
|
-
const styles = resolveUtility(parsed, theme);
|
|
3083
|
-
if (!styles) {
|
|
3084
|
-
if (process.env.NODE_ENV !== "production" && !parsed.isArbitrary && !isKnownUtility(parsed.utility) && !parsed.original.startsWith("__")) {
|
|
3085
|
-
kbachWarn(`Unknown class "${parsed.original}"`);
|
|
3086
|
-
}
|
|
3087
|
-
continue;
|
|
3088
|
-
}
|
|
3089
|
-
const bucketKey = parsed.modifiers.length === 0 ? "base" : parsed.modifiers.join(":");
|
|
3090
|
-
if (!result[bucketKey]) result[bucketKey] = {};
|
|
3091
|
-
Object.assign(result[bucketKey], styles);
|
|
3092
|
-
if (onWeb) {
|
|
3093
|
-
injectClassRule(parsed.original, bucketKey, styles, darkMode, parsed.important);
|
|
3094
|
-
}
|
|
3095
|
-
}
|
|
3096
|
-
cache.set(cacheKey, result);
|
|
3097
|
-
return result;
|
|
3098
|
-
}
|
|
3099
|
-
function flatten(resolved, isDark, state = {}, breakpoints = /* @__PURE__ */ new Set()) {
|
|
3100
|
-
const result = {};
|
|
3101
|
-
for (const [key, styles] of getSortedEntries(resolved)) {
|
|
3102
|
-
if (!styles) continue;
|
|
3103
|
-
if (key === "base") {
|
|
3104
|
-
Object.assign(result, styles);
|
|
3105
|
-
continue;
|
|
3106
|
-
}
|
|
3107
|
-
const mods = key.split(":");
|
|
3108
|
-
if (mods.every((mod) => matchModifier(mod, isDark, state, breakpoints))) {
|
|
3109
|
-
Object.assign(result, styles);
|
|
3110
|
-
}
|
|
3111
|
-
}
|
|
3112
|
-
if (isNative) {
|
|
3113
|
-
const defaultFont = getDefaultFontFamily();
|
|
3114
|
-
if (defaultFont && !("fontFamily" in result)) {
|
|
3115
|
-
result.fontFamily = defaultFont;
|
|
3116
|
-
}
|
|
3117
|
-
}
|
|
3118
|
-
if (!isNative) {
|
|
3119
|
-
const r = result;
|
|
3120
|
-
const ph = r.paddingHorizontal;
|
|
3121
|
-
if (ph !== void 0) {
|
|
3122
|
-
r.paddingLeft = ph;
|
|
3123
|
-
r.paddingRight = ph;
|
|
3124
|
-
delete r.paddingHorizontal;
|
|
3125
|
-
}
|
|
3126
|
-
const pv = r.paddingVertical;
|
|
3127
|
-
if (pv !== void 0) {
|
|
3128
|
-
r.paddingTop = pv;
|
|
3129
|
-
r.paddingBottom = pv;
|
|
3130
|
-
delete r.paddingVertical;
|
|
3131
|
-
}
|
|
3132
|
-
const mh = r.marginHorizontal;
|
|
3133
|
-
if (mh !== void 0) {
|
|
3134
|
-
r.marginLeft = mh;
|
|
3135
|
-
r.marginRight = mh;
|
|
3136
|
-
delete r.marginHorizontal;
|
|
3137
|
-
}
|
|
3138
|
-
const mv = r.marginVertical;
|
|
3139
|
-
if (mv !== void 0) {
|
|
3140
|
-
r.marginTop = mv;
|
|
3141
|
-
r.marginBottom = mv;
|
|
3142
|
-
delete r.marginVertical;
|
|
3143
|
-
}
|
|
3144
|
-
}
|
|
3145
|
-
return result;
|
|
3146
|
-
}
|
|
3147
|
-
function clearCache() {
|
|
3148
|
-
_injectedRules.clear();
|
|
3149
|
-
_ruleIndexByKey.clear();
|
|
3150
|
-
if (_styleEl) {
|
|
3151
|
-
_styleEl.remove();
|
|
3152
|
-
_styleEl = null;
|
|
3153
|
-
}
|
|
3154
|
-
if (_globalStyleEl) {
|
|
3155
|
-
_globalStyleEl.remove();
|
|
3156
|
-
_globalStyleEl = null;
|
|
3157
|
-
}
|
|
3158
|
-
}
|
|
3159
|
-
|
|
3160
|
-
// src/core/config.ts
|
|
3161
|
-
function deepMerge(base, override) {
|
|
3162
|
-
const result = { ...base };
|
|
3163
|
-
for (const key of Object.keys(override)) {
|
|
3164
|
-
const baseVal = base[key];
|
|
3165
|
-
const overVal = override[key];
|
|
3166
|
-
if (baseVal !== null && typeof baseVal === "object" && !Array.isArray(baseVal) && overVal !== null && typeof overVal === "object" && !Array.isArray(overVal)) {
|
|
3167
|
-
result[key] = deepMerge(
|
|
3168
|
-
baseVal,
|
|
3169
|
-
overVal
|
|
3170
|
-
);
|
|
3171
|
-
} else if (overVal !== void 0) {
|
|
3172
|
-
result[key] = overVal;
|
|
3173
|
-
}
|
|
3174
|
-
}
|
|
3175
|
-
return result;
|
|
3176
|
-
}
|
|
3177
|
-
var CONFIG_KEY = "__kbach_config_store__";
|
|
3178
|
-
function getConfigStore() {
|
|
3179
|
-
const g = globalThis;
|
|
3180
|
-
if (!g[CONFIG_KEY]) {
|
|
3181
|
-
g[CONFIG_KEY] = { resolved: null, listeners: /* @__PURE__ */ new Set(), customVariants: {} };
|
|
3182
|
-
}
|
|
3183
|
-
return g[CONFIG_KEY];
|
|
3184
|
-
}
|
|
3185
|
-
function getConfig() {
|
|
3186
|
-
const store = getConfigStore();
|
|
3187
|
-
if (store.resolved) return store.resolved;
|
|
3188
|
-
store.resolved = buildConfig({});
|
|
3189
|
-
return store.resolved;
|
|
3190
|
-
}
|
|
3191
|
-
function resolveOneRef(ref, colors) {
|
|
3192
|
-
const lastDash = ref.lastIndexOf("-");
|
|
3193
|
-
if (lastDash <= 0) return null;
|
|
3194
|
-
const name = ref.slice(0, lastDash);
|
|
3195
|
-
const shade = ref.slice(lastDash + 1);
|
|
3196
|
-
if (!/^\d+$/.test(shade)) return null;
|
|
3197
|
-
const entry = colors[name];
|
|
3198
|
-
if (!entry || typeof entry !== "object") return null;
|
|
3199
|
-
return entry[shade] ?? null;
|
|
3200
|
-
}
|
|
3201
|
-
function resolveColorRefs(colors) {
|
|
3202
|
-
const MAX_DEPTH = 5;
|
|
3203
|
-
function resolveChain(raw) {
|
|
3204
|
-
let current = raw;
|
|
3205
|
-
for (let i = 0; i < MAX_DEPTH; i++) {
|
|
3206
|
-
const next = resolveOneRef(current, colors);
|
|
3207
|
-
if (!next || next === current) break;
|
|
3208
|
-
current = next;
|
|
3209
|
-
}
|
|
3210
|
-
return current;
|
|
3211
|
-
}
|
|
3212
|
-
const out = {};
|
|
3213
|
-
for (const [key, val] of Object.entries(colors)) {
|
|
3214
|
-
if (typeof val === "string") {
|
|
3215
|
-
out[key] = resolveChain(val);
|
|
3216
|
-
} else {
|
|
3217
|
-
const shades = {};
|
|
3218
|
-
for (const [shade, hex] of Object.entries(val)) {
|
|
3219
|
-
shades[shade] = resolveChain(hex);
|
|
3220
|
-
}
|
|
3221
|
-
out[key] = shades;
|
|
3222
|
-
}
|
|
3223
|
-
}
|
|
3224
|
-
return out;
|
|
3225
|
-
}
|
|
3226
|
-
function buildConfig(userConfig) {
|
|
3227
|
-
let theme = { ...defaultTheme };
|
|
3228
|
-
if (userConfig.theme) {
|
|
3229
|
-
theme = { ...theme, ...userConfig.theme };
|
|
3230
|
-
}
|
|
3231
|
-
if (userConfig.extend) {
|
|
3232
|
-
const extendConfig = userConfig.extend;
|
|
3233
|
-
const { theme: nestedTheme, ...directKeys } = extendConfig;
|
|
3234
|
-
const extSources = [];
|
|
3235
|
-
if (nestedTheme) extSources.push(nestedTheme);
|
|
3236
|
-
if (Object.keys(directKeys).length) extSources.push(directKeys);
|
|
3237
|
-
for (const ext of extSources) {
|
|
3238
|
-
for (const [key, value] of Object.entries(ext)) {
|
|
3239
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3240
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3241
|
-
kbachWarn(`extend.${key} should be an object, got ${typeof value} \u2014 skipped`);
|
|
3242
|
-
}
|
|
3243
|
-
continue;
|
|
3244
|
-
}
|
|
3245
|
-
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
3246
|
-
theme[key] = deepMerge(
|
|
3247
|
-
theme[key] ?? {},
|
|
3248
|
-
value
|
|
3249
|
-
);
|
|
3250
|
-
}
|
|
3251
|
-
}
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
theme = { ...theme, colors: resolveColorRefs(theme.colors) };
|
|
3255
|
-
const resolved = {
|
|
3256
|
-
darkMode: userConfig.darkMode ?? "attribute",
|
|
3257
|
-
theme,
|
|
3258
|
-
plugins: userConfig.plugins ?? []
|
|
3259
|
-
};
|
|
3260
|
-
if (userConfig.plugins !== void 0) {
|
|
3261
|
-
clearPluginUtilities();
|
|
3262
|
-
clearPluginModifiers();
|
|
3263
|
-
}
|
|
3264
|
-
const _store = getConfigStore();
|
|
3265
|
-
for (const k of Object.keys(_store.customVariants)) delete _store.customVariants[k];
|
|
3266
|
-
const pluginAPI = makePluginAPI(resolved.theme);
|
|
3267
|
-
for (const plugin of resolved.plugins) {
|
|
3268
|
-
plugin(pluginAPI);
|
|
3269
|
-
}
|
|
3270
|
-
const rawSans = theme.fontFamily?.sans;
|
|
3271
|
-
const sansFontValue = Array.isArray(rawSans) ? rawSans[0] : rawSans;
|
|
3272
|
-
setDefaultFontFamily(sansFontValue && sansFontValue !== "System" ? sansFontValue : void 0);
|
|
3273
|
-
injectGlobalStyles(resolved.theme);
|
|
3274
|
-
return resolved;
|
|
3275
|
-
}
|
|
3276
|
-
function _selectorToModifierDef(selector) {
|
|
3277
|
-
const s = selector.trim();
|
|
3278
|
-
if (s.startsWith("@media ")) {
|
|
3279
|
-
return { mediaQuery: s.slice(7), jsBehavior: "css-only", forcesImportant: true };
|
|
3280
|
-
}
|
|
3281
|
-
if (s.startsWith("::") || s.startsWith(":") && !s.includes(" ") && !s.includes("&") && !s.includes("(")) {
|
|
3282
|
-
return { pseudo: s, jsBehavior: "css-only", forcesImportant: true };
|
|
3283
|
-
}
|
|
3284
|
-
return { ancestorSelector: s.endsWith(" ") ? s : `${s} `, jsBehavior: "css-only", forcesImportant: true };
|
|
3285
|
-
}
|
|
3286
|
-
function makePluginAPI(theme) {
|
|
3287
|
-
const standalone = getPluginStandaloneMap();
|
|
3288
|
-
return {
|
|
3289
|
-
addUtility(name, styles) {
|
|
3290
|
-
standalone[name] = styles;
|
|
3291
|
-
},
|
|
3292
|
-
addVariant(name, selectorOrDef) {
|
|
3293
|
-
const def = typeof selectorOrDef === "string" ? _selectorToModifierDef(selectorOrDef) : selectorOrDef;
|
|
3294
|
-
const selector = typeof selectorOrDef === "string" ? selectorOrDef : selectorOrDef.pseudo ?? selectorOrDef.mediaQuery ?? selectorOrDef.ancestorSelector ?? null;
|
|
3295
|
-
if (selector !== null && selector !== name) customVariants[name] = selector;
|
|
3296
|
-
registerModifier(name, def);
|
|
3297
|
-
},
|
|
3298
|
-
theme(path, defaultValue) {
|
|
3299
|
-
const parts = path.replace(/\[([^\]]+)\]/g, ".$1").split(".");
|
|
3300
|
-
let current = theme;
|
|
3301
|
-
for (const part of parts) {
|
|
3302
|
-
if (current === null || typeof current !== "object") return defaultValue;
|
|
3303
|
-
current = current[part];
|
|
3304
|
-
}
|
|
3305
|
-
return current ?? defaultValue;
|
|
3306
|
-
},
|
|
3307
|
-
e(className) {
|
|
3308
|
-
return className.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
3309
|
-
}
|
|
3310
|
-
};
|
|
3311
|
-
}
|
|
3312
|
-
function onConfigChange(listener) {
|
|
3313
|
-
const store = getConfigStore();
|
|
3314
|
-
store.listeners.add(listener);
|
|
3315
|
-
return () => store.listeners.delete(listener);
|
|
3316
|
-
}
|
|
3317
|
-
function updateConfig(userConfig) {
|
|
3318
|
-
const store = getConfigStore();
|
|
3319
|
-
store.resolved = buildConfig(userConfig);
|
|
3320
|
-
store._src = userConfig;
|
|
3321
|
-
clearCache();
|
|
3322
|
-
for (const listener of store.listeners) {
|
|
3323
|
-
listener(store.resolved);
|
|
3324
|
-
}
|
|
3325
|
-
}
|
|
3326
|
-
function initConfig(userConfig) {
|
|
3327
|
-
if (getConfigStore()._src === userConfig) return;
|
|
3328
|
-
updateConfig(userConfig);
|
|
3329
|
-
}
|
|
3330
|
-
var customVariants = new Proxy(
|
|
3331
|
-
{},
|
|
3332
|
-
{
|
|
3333
|
-
get(_t, p) {
|
|
3334
|
-
return typeof p === "string" ? getConfigStore().customVariants[p] : void 0;
|
|
3335
|
-
},
|
|
3336
|
-
set(_t, p, v) {
|
|
3337
|
-
if (typeof p === "string") getConfigStore().customVariants[p] = v;
|
|
3338
|
-
return true;
|
|
3339
|
-
},
|
|
3340
|
-
ownKeys() {
|
|
3341
|
-
return Object.keys(getConfigStore().customVariants);
|
|
3342
|
-
},
|
|
3343
|
-
getOwnPropertyDescriptor(_t, p) {
|
|
3344
|
-
if (typeof p !== "string") return void 0;
|
|
3345
|
-
const v = getConfigStore().customVariants[p];
|
|
3346
|
-
return v !== void 0 ? { value: v, writable: true, enumerable: true, configurable: true } : void 0;
|
|
3347
|
-
}
|
|
3348
|
-
}
|
|
3349
|
-
);
|
|
3350
|
-
|
|
3351
|
-
// src/core/darkModeStore.ts
|
|
3352
|
-
var KEY = "__kbach_dark_store__";
|
|
3353
|
-
function getStore2() {
|
|
3354
|
-
const g = globalThis;
|
|
3355
|
-
if (!g[KEY]) {
|
|
3356
|
-
g[KEY] = { isDark: false, notifiedIsDark: false, subscribers: /* @__PURE__ */ new Set() };
|
|
3357
|
-
}
|
|
3358
|
-
return g[KEY];
|
|
3359
|
-
}
|
|
3360
|
-
function syncGlobalDarkMode(isDark) {
|
|
3361
|
-
getStore2().isDark = isDark;
|
|
3362
|
-
}
|
|
3363
|
-
function setGlobalDarkMode(isDark) {
|
|
3364
|
-
const store = getStore2();
|
|
3365
|
-
store.isDark = isDark;
|
|
3366
|
-
if (store.notifiedIsDark === isDark) return;
|
|
3367
|
-
store.notifiedIsDark = isDark;
|
|
3368
|
-
for (const sub of store.subscribers) sub();
|
|
3369
|
-
}
|
|
3370
|
-
function getGlobalDarkMode() {
|
|
3371
|
-
return getStore2().isDark;
|
|
3372
|
-
}
|
|
3373
|
-
function subscribeGlobalDarkMode(callback) {
|
|
3374
|
-
const store = getStore2();
|
|
3375
|
-
store.subscribers.add(callback);
|
|
3376
|
-
return () => store.subscribers.delete(callback);
|
|
3377
|
-
}
|
|
3378
|
-
|
|
3379
|
-
// src/useColors.ts
|
|
89
|
+
var import_core = require("./core");
|
|
3380
90
|
function applyOpacity(color, opacity) {
|
|
3381
91
|
const a = Math.max(0, Math.min(1, opacity / 100));
|
|
3382
92
|
if (color.startsWith("#")) {
|
|
3383
|
-
const rgb = parseHexRgb(color);
|
|
93
|
+
const rgb = (0, import_core.parseHexRgb)(color);
|
|
3384
94
|
if (!rgb) return color;
|
|
3385
95
|
const [r, g, b] = rgb;
|
|
3386
96
|
return `rgba(${r},${g},${b},${a})`;
|
|
@@ -3433,26 +143,44 @@ function useColors() {
|
|
|
3433
143
|
return (0, import_react2.useMemo)(() => wrapColors(config.theme.colors), [config.theme.colors]);
|
|
3434
144
|
}
|
|
3435
145
|
|
|
146
|
+
// src/useSpacing.ts
|
|
147
|
+
var import_react3 = require("react");
|
|
148
|
+
function wrapSpacing(rawSpacing) {
|
|
149
|
+
return rawSpacing;
|
|
150
|
+
}
|
|
151
|
+
function useSpacing() {
|
|
152
|
+
const { config } = useTheme();
|
|
153
|
+
return (0, import_react3.useMemo)(() => wrapSpacing(config.theme.spacing), [config.theme.spacing]);
|
|
154
|
+
}
|
|
155
|
+
|
|
3436
156
|
// src/ThemeProvider.tsx
|
|
3437
|
-
var
|
|
157
|
+
var import_react5 = require("react");
|
|
3438
158
|
|
|
3439
159
|
// src/useSyncExternalStoreShim.ts
|
|
3440
|
-
var
|
|
3441
|
-
var useSyncExternalStore =
|
|
3442
|
-
const
|
|
3443
|
-
|
|
3444
|
-
|
|
160
|
+
var import_react4 = __toESM(require("react"));
|
|
161
|
+
var useSyncExternalStore = import_react4.default.useSyncExternalStore ?? function useSyncExternalStoreFallback(subscribe, getSnapshot, getServerSnapshot) {
|
|
162
|
+
const isServer = typeof window === "undefined";
|
|
163
|
+
const [, forceUpdate] = import_react4.default.useReducer((n) => n + 1, 0);
|
|
164
|
+
const value = isServer && getServerSnapshot ? getServerSnapshot() : getSnapshot();
|
|
165
|
+
import_react4.default.useEffect(() => {
|
|
166
|
+
if (getSnapshot() !== value) forceUpdate();
|
|
167
|
+
return subscribe(forceUpdate);
|
|
168
|
+
}, [subscribe]);
|
|
169
|
+
return value;
|
|
3445
170
|
};
|
|
3446
171
|
|
|
3447
172
|
// src/ThemeProvider.tsx
|
|
173
|
+
var import_core2 = require("./core");
|
|
3448
174
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
3449
|
-
var useIsomorphicLayoutEffect = isWeb || isNative ?
|
|
175
|
+
var useIsomorphicLayoutEffect = import_core2.isWeb || import_core2.isNative ? import_react5.useLayoutEffect : import_react5.useEffect;
|
|
3450
176
|
var STORAGE_KEY = "kbach-theme";
|
|
3451
177
|
var _mountedProviderCount = 0;
|
|
3452
178
|
var _warnedMultipleProviders = false;
|
|
179
|
+
var _mountedConfigOverrideCount = 0;
|
|
180
|
+
var _warnedConfigOverride = false;
|
|
3453
181
|
function loadPersistedMode() {
|
|
3454
182
|
try {
|
|
3455
|
-
if (isWeb) return localStorage.getItem(STORAGE_KEY);
|
|
183
|
+
if (import_core2.isWeb) return localStorage.getItem(STORAGE_KEY);
|
|
3456
184
|
return null;
|
|
3457
185
|
} catch {
|
|
3458
186
|
return null;
|
|
@@ -3460,12 +188,12 @@ function loadPersistedMode() {
|
|
|
3460
188
|
}
|
|
3461
189
|
function persistMode(mode) {
|
|
3462
190
|
try {
|
|
3463
|
-
if (isWeb) localStorage.setItem(STORAGE_KEY, mode);
|
|
191
|
+
if (import_core2.isWeb) localStorage.setItem(STORAGE_KEY, mode);
|
|
3464
192
|
} catch {
|
|
3465
193
|
}
|
|
3466
194
|
}
|
|
3467
195
|
function subscribeSystemScheme(callback) {
|
|
3468
|
-
if (!isWeb || typeof window === "undefined") return () => {
|
|
196
|
+
if (!import_core2.isWeb || typeof window === "undefined") return () => {
|
|
3469
197
|
};
|
|
3470
198
|
const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
3471
199
|
if (!mq) return () => {
|
|
@@ -3474,14 +202,14 @@ function subscribeSystemScheme(callback) {
|
|
|
3474
202
|
return () => mq.removeEventListener("change", callback);
|
|
3475
203
|
}
|
|
3476
204
|
function getSystemScheme() {
|
|
3477
|
-
if (!isWeb || typeof window === "undefined") return "light";
|
|
205
|
+
if (!import_core2.isWeb || typeof window === "undefined") return "light";
|
|
3478
206
|
return window.matchMedia?.("(prefers-color-scheme: dark)")?.matches ? "dark" : "light";
|
|
3479
207
|
}
|
|
3480
208
|
function getSystemSchemeServerSnapshot() {
|
|
3481
209
|
return "light";
|
|
3482
210
|
}
|
|
3483
211
|
function applyWebTheme(resolvedMode, strategy) {
|
|
3484
|
-
if (!isWeb) return;
|
|
212
|
+
if (!import_core2.isWeb) return;
|
|
3485
213
|
const root = document.documentElement;
|
|
3486
214
|
if (strategy === "attribute") {
|
|
3487
215
|
root.setAttribute("data-theme", resolvedMode);
|
|
@@ -3498,45 +226,62 @@ function ThemeProvider({
|
|
|
3498
226
|
config: configOverride,
|
|
3499
227
|
disablePersistence = false
|
|
3500
228
|
}) {
|
|
3501
|
-
const [resolvedConfig, setResolvedConfig] = (0,
|
|
3502
|
-
() => configOverride ? buildConfig(configOverride) : getConfig()
|
|
229
|
+
const [resolvedConfig, setResolvedConfig] = (0, import_react5.useState)(
|
|
230
|
+
() => configOverride ? (0, import_core2.buildConfig)(configOverride) : (0, import_core2.getConfig)()
|
|
3503
231
|
);
|
|
3504
|
-
(0,
|
|
232
|
+
const _prevConfigOverrideRef = (0, import_react5.useRef)(void 0);
|
|
233
|
+
if (configOverride && _prevConfigOverrideRef.current !== configOverride) {
|
|
234
|
+
_prevConfigOverrideRef.current = configOverride;
|
|
235
|
+
(0, import_core2.updateConfig)(configOverride);
|
|
236
|
+
const fresh = (0, import_core2.getConfig)();
|
|
237
|
+
if (fresh !== resolvedConfig) setResolvedConfig(fresh);
|
|
238
|
+
}
|
|
239
|
+
(0, import_react5.useEffect)(() => {
|
|
3505
240
|
_mountedProviderCount++;
|
|
3506
|
-
if (
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
241
|
+
if (configOverride) _mountedConfigOverrideCount++;
|
|
242
|
+
if (process.env.NODE_ENV !== "production") {
|
|
243
|
+
if (_mountedProviderCount > 1 && !_warnedMultipleProviders) {
|
|
244
|
+
_warnedMultipleProviders = true;
|
|
245
|
+
(0, import_core2.kbachWarn)(
|
|
246
|
+
"Multiple <ThemeProvider> instances are mounted at once. Dark mode and responsive width are shared through one global store, so whichever provider rendered most recently wins for every consumer \u2014 nested or per-section theming is not isolated between providers."
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
if (_mountedConfigOverrideCount > 1 && !_warnedConfigOverride) {
|
|
250
|
+
_warnedConfigOverride = true;
|
|
251
|
+
(0, import_core2.kbachWarn)(
|
|
252
|
+
"Multiple <ThemeProvider config={...}> overrides are mounted at once. The resolved config is shared through the same global store as dark mode/width (see the multiple-providers warning), so per-tree config overrides are not actually isolated between providers \u2014 plain className/kb elements with no hover:/dark:/sm: modifier resolve against whichever override last committed, not necessarily their nearest ancestor <ThemeProvider>."
|
|
253
|
+
);
|
|
254
|
+
}
|
|
3511
255
|
}
|
|
3512
256
|
return () => {
|
|
3513
257
|
_mountedProviderCount--;
|
|
258
|
+
if (configOverride) _mountedConfigOverrideCount--;
|
|
3514
259
|
};
|
|
3515
260
|
}, []);
|
|
3516
|
-
const [webWidth, setWebWidth] = (0,
|
|
3517
|
-
const effectiveWidth = windowWidthProp ?? (isWeb ? webWidth : 0);
|
|
3518
|
-
const numericScreens = (0,
|
|
261
|
+
const [webWidth, setWebWidth] = (0, import_react5.useState)(0);
|
|
262
|
+
const effectiveWidth = windowWidthProp ?? (import_core2.isWeb ? webWidth : 0);
|
|
263
|
+
const numericScreens = (0, import_react5.useMemo)(() => {
|
|
3519
264
|
const out = {};
|
|
3520
265
|
for (const [k, v] of Object.entries(resolvedConfig.theme.screens ?? {})) {
|
|
3521
266
|
out[k] = typeof v === "number" ? v : parseInt(String(v), 10);
|
|
3522
267
|
}
|
|
3523
268
|
return out;
|
|
3524
269
|
}, [resolvedConfig.theme.screens]);
|
|
3525
|
-
const _prevWidthRef = (0,
|
|
270
|
+
const _prevWidthRef = (0, import_react5.useRef)(-1);
|
|
3526
271
|
if (_prevWidthRef.current !== effectiveWidth) {
|
|
3527
272
|
_prevWidthRef.current = effectiveWidth;
|
|
3528
|
-
syncGlobalWidth(effectiveWidth);
|
|
273
|
+
(0, import_core2.syncGlobalWidth)(effectiveWidth);
|
|
3529
274
|
}
|
|
3530
|
-
const _prevScreensRef = (0,
|
|
275
|
+
const _prevScreensRef = (0, import_react5.useRef)(null);
|
|
3531
276
|
if (_prevScreensRef.current !== numericScreens) {
|
|
3532
277
|
_prevScreensRef.current = numericScreens;
|
|
3533
|
-
syncGlobalScreens(numericScreens);
|
|
278
|
+
(0, import_core2.syncGlobalScreens)(numericScreens);
|
|
3534
279
|
}
|
|
3535
|
-
(0,
|
|
3536
|
-
setGlobalWidth(effectiveWidth);
|
|
280
|
+
(0, import_react5.useEffect)(() => {
|
|
281
|
+
(0, import_core2.setGlobalWidth)(effectiveWidth);
|
|
3537
282
|
}, [effectiveWidth]);
|
|
3538
|
-
(0,
|
|
3539
|
-
if (!isWeb || typeof window === "undefined") return;
|
|
283
|
+
(0, import_react5.useEffect)(() => {
|
|
284
|
+
if (!import_core2.isWeb || typeof window === "undefined") return;
|
|
3540
285
|
setWebWidth(window.innerWidth);
|
|
3541
286
|
let raf = 0;
|
|
3542
287
|
const update = () => {
|
|
@@ -3544,7 +289,7 @@ function ThemeProvider({
|
|
|
3544
289
|
raf = requestAnimationFrame(() => {
|
|
3545
290
|
const w = window.innerWidth;
|
|
3546
291
|
setWebWidth(w);
|
|
3547
|
-
setGlobalWidth(w);
|
|
292
|
+
(0, import_core2.setGlobalWidth)(w);
|
|
3548
293
|
});
|
|
3549
294
|
};
|
|
3550
295
|
window.addEventListener("resize", update);
|
|
@@ -3558,15 +303,15 @@ function ThemeProvider({
|
|
|
3558
303
|
getSystemScheme,
|
|
3559
304
|
getSystemSchemeServerSnapshot
|
|
3560
305
|
);
|
|
3561
|
-
const systemScheme = isWeb ? webScheme : colorScheme === "dark" ? "dark" : "light";
|
|
3562
|
-
const [mode, _setMode] = (0,
|
|
3563
|
-
(0,
|
|
306
|
+
const systemScheme = import_core2.isWeb ? webScheme : colorScheme === "dark" ? "dark" : "light";
|
|
307
|
+
const [mode, _setMode] = (0, import_react5.useState)(defaultMode);
|
|
308
|
+
(0, import_react5.useEffect)(() => {
|
|
3564
309
|
if (disablePersistence) return;
|
|
3565
310
|
const persisted = loadPersistedMode();
|
|
3566
311
|
if (persisted) _setMode(persisted);
|
|
3567
312
|
}, []);
|
|
3568
|
-
(0,
|
|
3569
|
-
if (disablePersistence || !isWeb || typeof window === "undefined") return;
|
|
313
|
+
(0, import_react5.useEffect)(() => {
|
|
314
|
+
if (disablePersistence || !import_core2.isWeb || typeof window === "undefined") return;
|
|
3570
315
|
const onStorage = (e) => {
|
|
3571
316
|
if (e.key !== STORAGE_KEY || e.newValue == null) return;
|
|
3572
317
|
if (e.newValue === "light" || e.newValue === "dark" || e.newValue === "system") {
|
|
@@ -3576,29 +321,24 @@ function ThemeProvider({
|
|
|
3576
321
|
window.addEventListener("storage", onStorage);
|
|
3577
322
|
return () => window.removeEventListener("storage", onStorage);
|
|
3578
323
|
}, [disablePersistence]);
|
|
3579
|
-
const setMode = (0,
|
|
324
|
+
const setMode = (0, import_react5.useCallback)((next) => {
|
|
3580
325
|
_setMode(next);
|
|
3581
326
|
if (!disablePersistence) persistMode(next);
|
|
3582
327
|
}, [disablePersistence]);
|
|
3583
|
-
const toggle = (0,
|
|
328
|
+
const toggle = (0, import_react5.useCallback)(() => {
|
|
3584
329
|
setMode(mode === "dark" || mode === "system" && systemScheme === "dark" ? "light" : "dark");
|
|
3585
330
|
}, [mode, systemScheme, setMode]);
|
|
3586
331
|
const resolvedMode = mode === "system" ? systemScheme : mode;
|
|
3587
332
|
const isDark = resolvedMode === "dark";
|
|
3588
|
-
syncGlobalDarkMode(isDark);
|
|
333
|
+
(0, import_core2.syncGlobalDarkMode)(isDark);
|
|
3589
334
|
useIsomorphicLayoutEffect(() => {
|
|
3590
335
|
applyWebTheme(resolvedMode, resolvedConfig.darkMode);
|
|
3591
|
-
setGlobalDarkMode(isDark);
|
|
336
|
+
(0, import_core2.setGlobalDarkMode)(isDark);
|
|
3592
337
|
}, [isDark, resolvedMode, resolvedConfig.darkMode]);
|
|
3593
|
-
(0,
|
|
3594
|
-
if (!configOverride) return;
|
|
3595
|
-
updateConfig(configOverride);
|
|
3596
|
-
setResolvedConfig(getConfig());
|
|
3597
|
-
}, [configOverride]);
|
|
3598
|
-
(0, import_react4.useEffect)(() => {
|
|
338
|
+
(0, import_react5.useEffect)(() => {
|
|
3599
339
|
if (configOverride) return;
|
|
3600
340
|
let mounted = true;
|
|
3601
|
-
const unsub = onConfigChange((config) => {
|
|
341
|
+
const unsub = (0, import_core2.onConfigChange)((config) => {
|
|
3602
342
|
if (mounted) setResolvedConfig(config);
|
|
3603
343
|
});
|
|
3604
344
|
return () => {
|
|
@@ -3606,7 +346,7 @@ function ThemeProvider({
|
|
|
3606
346
|
unsub();
|
|
3607
347
|
};
|
|
3608
348
|
}, [configOverride]);
|
|
3609
|
-
const contextValue = (0,
|
|
349
|
+
const contextValue = (0, import_react5.useMemo)(
|
|
3610
350
|
() => ({ mode, resolvedMode, isDark, setMode, toggle, config: resolvedConfig }),
|
|
3611
351
|
[mode, resolvedMode, isDark, setMode, toggle, resolvedConfig]
|
|
3612
352
|
);
|
|
@@ -3614,36 +354,40 @@ function ThemeProvider({
|
|
|
3614
354
|
}
|
|
3615
355
|
|
|
3616
356
|
// src/KbachReset.tsx
|
|
357
|
+
var import_core3 = require("./core");
|
|
3617
358
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3618
359
|
function KbachReset() {
|
|
3619
|
-
if (isNative) return null;
|
|
3620
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { id: RESET_STYLE_ID, children: BASE_RESET });
|
|
360
|
+
if (import_core3.isNative) return null;
|
|
361
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { id: import_core3.RESET_STYLE_ID, children: import_core3.BASE_RESET });
|
|
3621
362
|
}
|
|
3622
363
|
|
|
3623
364
|
// src/styled.tsx
|
|
3624
|
-
var
|
|
365
|
+
var import_react6 = __toESM(require("react"));
|
|
366
|
+
var import_core7 = require("./core");
|
|
3625
367
|
|
|
3626
368
|
// src/useGlobalDarkMode.ts
|
|
369
|
+
var import_core4 = require("./core");
|
|
3627
370
|
var NOOP_SUB = (_) => () => {
|
|
3628
371
|
};
|
|
3629
372
|
var FALSE_SNAP = () => false;
|
|
3630
373
|
function useGlobalDarkMode() {
|
|
3631
374
|
return useSyncExternalStore(
|
|
3632
|
-
subscribeGlobalDarkMode,
|
|
3633
|
-
getGlobalDarkMode,
|
|
375
|
+
import_core4.subscribeGlobalDarkMode,
|
|
376
|
+
import_core4.getGlobalDarkMode,
|
|
3634
377
|
() => false
|
|
3635
378
|
// SSR: default light
|
|
3636
379
|
);
|
|
3637
380
|
}
|
|
3638
381
|
function useConditionalGlobalDarkMode(active) {
|
|
3639
382
|
return useSyncExternalStore(
|
|
3640
|
-
active ? subscribeGlobalDarkMode : NOOP_SUB,
|
|
3641
|
-
active ? getGlobalDarkMode : FALSE_SNAP,
|
|
383
|
+
active ? import_core4.subscribeGlobalDarkMode : NOOP_SUB,
|
|
384
|
+
active ? import_core4.getGlobalDarkMode : FALSE_SNAP,
|
|
3642
385
|
FALSE_SNAP
|
|
3643
386
|
);
|
|
3644
387
|
}
|
|
3645
388
|
|
|
3646
389
|
// src/useGlobalWidth.ts
|
|
390
|
+
var import_core5 = require("./core");
|
|
3647
391
|
var NOOP_SUB2 = (_) => () => {
|
|
3648
392
|
};
|
|
3649
393
|
var ZERO_SNAP = () => 0;
|
|
@@ -3678,22 +422,23 @@ function getWebWidth() {
|
|
|
3678
422
|
}
|
|
3679
423
|
function useGlobalWidth() {
|
|
3680
424
|
return useSyncExternalStore(
|
|
3681
|
-
isWeb ? subscribeWebWidth : subscribeGlobalWidth,
|
|
3682
|
-
isWeb ? getWebWidth : getGlobalWidth,
|
|
425
|
+
import_core5.isWeb ? subscribeWebWidth : import_core5.subscribeGlobalWidth,
|
|
426
|
+
import_core5.isWeb ? getWebWidth : import_core5.getGlobalWidth,
|
|
3683
427
|
ZERO_SNAP
|
|
3684
428
|
);
|
|
3685
429
|
}
|
|
3686
430
|
function useConditionalWidth(active) {
|
|
3687
431
|
return useSyncExternalStore(
|
|
3688
|
-
active ? isWeb ? subscribeWebWidth : subscribeGlobalWidth : NOOP_SUB2,
|
|
3689
|
-
active ? isWeb ? getWebWidth : getGlobalWidth : ZERO_SNAP,
|
|
432
|
+
active ? import_core5.isWeb ? subscribeWebWidth : import_core5.subscribeGlobalWidth : NOOP_SUB2,
|
|
433
|
+
active ? import_core5.isWeb ? getWebWidth : import_core5.getGlobalWidth : ZERO_SNAP,
|
|
3690
434
|
ZERO_SNAP
|
|
3691
435
|
);
|
|
3692
436
|
}
|
|
3693
437
|
|
|
3694
438
|
// src/shared-utils.ts
|
|
439
|
+
var import_core6 = require("./core");
|
|
3695
440
|
function hasResponsiveBuckets(resolved) {
|
|
3696
|
-
const responsiveMods = getResponsiveModifiers();
|
|
441
|
+
const responsiveMods = (0, import_core6.getResponsiveModifiers)();
|
|
3697
442
|
for (const key of Object.keys(resolved)) {
|
|
3698
443
|
if (key === "base") continue;
|
|
3699
444
|
for (const mod of key.split(":")) {
|
|
@@ -3703,7 +448,7 @@ function hasResponsiveBuckets(resolved) {
|
|
|
3703
448
|
return false;
|
|
3704
449
|
}
|
|
3705
450
|
function hasInteractiveBuckets(resolved) {
|
|
3706
|
-
const interactiveMods = getInteractiveModifiers();
|
|
451
|
+
const interactiveMods = (0, import_core6.getInteractiveModifiers)();
|
|
3707
452
|
for (const key of Object.keys(resolved)) {
|
|
3708
453
|
if (key === "base") continue;
|
|
3709
454
|
for (const mod of key.split(":")) {
|
|
@@ -4026,7 +771,7 @@ function transformToWebProps(originalName, tag, props) {
|
|
|
4026
771
|
|
|
4027
772
|
// src/styled.tsx
|
|
4028
773
|
function styled(Component, baseClasses = "") {
|
|
4029
|
-
const Styled = (0,
|
|
774
|
+
const Styled = (0, import_react6.forwardRef)(
|
|
4030
775
|
(props, ref) => {
|
|
4031
776
|
const {
|
|
4032
777
|
kb: extraClasses,
|
|
@@ -4046,49 +791,49 @@ function styled(Component, baseClasses = "") {
|
|
|
4046
791
|
const disabled = !!props.disabled;
|
|
4047
792
|
const checked = !!props.checked;
|
|
4048
793
|
const { config } = useTheme();
|
|
4049
|
-
const isWebPlatform = getEffectiveIsWeb();
|
|
794
|
+
const isWebPlatform = (0, import_core7.getEffectiveIsWeb)();
|
|
4050
795
|
const isDark = useConditionalGlobalDarkMode(!isWebPlatform);
|
|
4051
|
-
const [pressed, setPressed] = (0,
|
|
4052
|
-
const [hovered, setHovered] = (0,
|
|
4053
|
-
const [focused, setFocused] = (0,
|
|
4054
|
-
const handlePressIn = (0,
|
|
796
|
+
const [pressed, setPressed] = (0, import_react6.useState)(false);
|
|
797
|
+
const [hovered, setHovered] = (0, import_react6.useState)(false);
|
|
798
|
+
const [focused, setFocused] = (0, import_react6.useState)(false);
|
|
799
|
+
const handlePressIn = (0, import_react6.useCallback)(chain(onPressIn, () => {
|
|
4055
800
|
if (!isWebPlatform) setPressed(true);
|
|
4056
801
|
}), [onPressIn, isWebPlatform]);
|
|
4057
|
-
const handlePressOut = (0,
|
|
802
|
+
const handlePressOut = (0, import_react6.useCallback)(chain(onPressOut, () => {
|
|
4058
803
|
if (!isWebPlatform) setPressed(false);
|
|
4059
804
|
}), [onPressOut, isWebPlatform]);
|
|
4060
|
-
const handlePointerDown = (0,
|
|
805
|
+
const handlePointerDown = (0, import_react6.useCallback)(chain(onPointerDown, () => {
|
|
4061
806
|
if (!isWebPlatform) setPressed(true);
|
|
4062
807
|
}), [onPointerDown, isWebPlatform]);
|
|
4063
|
-
const handlePointerUp = (0,
|
|
808
|
+
const handlePointerUp = (0, import_react6.useCallback)(chain(onPointerUp, () => {
|
|
4064
809
|
if (!isWebPlatform) setPressed(false);
|
|
4065
810
|
}), [onPointerUp, isWebPlatform]);
|
|
4066
|
-
const handlePointerLeave = (0,
|
|
811
|
+
const handlePointerLeave = (0, import_react6.useCallback)(chain(onPointerLeave, () => {
|
|
4067
812
|
if (!isWebPlatform) setPressed(false);
|
|
4068
813
|
}), [onPointerLeave, isWebPlatform]);
|
|
4069
|
-
const handlePointerCancel = (0,
|
|
814
|
+
const handlePointerCancel = (0, import_react6.useCallback)(chain(onPointerCancel, () => {
|
|
4070
815
|
if (!isWebPlatform) setPressed(false);
|
|
4071
816
|
}), [onPointerCancel, isWebPlatform]);
|
|
4072
|
-
const handleMouseEnter = (0,
|
|
817
|
+
const handleMouseEnter = (0, import_react6.useCallback)(chain(onMouseEnter, () => {
|
|
4073
818
|
if (!isWebPlatform) setHovered(true);
|
|
4074
819
|
}), [onMouseEnter, isWebPlatform]);
|
|
4075
|
-
const handleMouseLeave = (0,
|
|
820
|
+
const handleMouseLeave = (0, import_react6.useCallback)(chain(onMouseLeave, () => {
|
|
4076
821
|
if (!isWebPlatform) setHovered(false);
|
|
4077
822
|
}), [onMouseLeave, isWebPlatform]);
|
|
4078
|
-
const handleFocus = (0,
|
|
823
|
+
const handleFocus = (0, import_react6.useCallback)(chain(onFocus, () => {
|
|
4079
824
|
if (!isWebPlatform) setFocused(true);
|
|
4080
825
|
}), [onFocus, isWebPlatform]);
|
|
4081
|
-
const handleBlur = (0,
|
|
826
|
+
const handleBlur = (0, import_react6.useCallback)(chain(onBlur, () => {
|
|
4082
827
|
if (!isWebPlatform) setFocused(false);
|
|
4083
828
|
}), [onBlur, isWebPlatform]);
|
|
4084
829
|
const combined = extraClasses ? `${baseClasses} ${extraClasses}` : baseClasses;
|
|
4085
|
-
const resolved = (0,
|
|
4086
|
-
const hasInteractive = (0,
|
|
830
|
+
const resolved = (0, import_react6.useMemo)(() => (0, import_core7.resolve)(combined, config.theme, config.darkMode), [combined, config.theme, config.darkMode]);
|
|
831
|
+
const hasInteractive = (0, import_react6.useMemo)(() => hasInteractiveBuckets(resolved), [resolved]);
|
|
4087
832
|
const needsWidth = hasResponsiveBuckets(resolved);
|
|
4088
833
|
const width = useConditionalWidth(needsWidth && !isWebPlatform);
|
|
4089
|
-
const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
|
|
4090
|
-
const computedStyle = (0,
|
|
4091
|
-
() => isWebPlatform ? {} : flatten(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
|
|
834
|
+
const breakpoints = needsWidth ? (0, import_core7.getActiveBreakpoints)(width) : EMPTY_BREAKPOINTS;
|
|
835
|
+
const computedStyle = (0, import_react6.useMemo)(
|
|
836
|
+
() => isWebPlatform ? {} : (0, import_core7.flatten)(resolved, isDark, { pressed, hover: hovered, focus: focused, disabled, checked }, breakpoints),
|
|
4092
837
|
[resolved, isDark, pressed, hovered, focused, disabled, checked, width]
|
|
4093
838
|
// eslint-disable-line react-hooks/exhaustive-deps
|
|
4094
839
|
);
|
|
@@ -4098,12 +843,12 @@ function styled(Component, baseClasses = "") {
|
|
|
4098
843
|
const effectiveComponent = webTag ?? Component;
|
|
4099
844
|
const componentName2 = Component.displayName ?? Component.name ?? "";
|
|
4100
845
|
const effectiveRest = webTag && componentName2 ? transformToWebProps(componentName2, webTag, rest) : rest;
|
|
4101
|
-
return
|
|
846
|
+
return import_react6.default.createElement(effectiveComponent, {
|
|
4102
847
|
ref,
|
|
4103
848
|
...effectiveRest,
|
|
4104
849
|
style: finalStyle,
|
|
4105
850
|
// className lets injected CSS rules (group-hover:, before:, print:, etc.) match the element.
|
|
4106
|
-
...isWebPlatform && combined ? { className: normalizeClassString(combined) } : {},
|
|
851
|
+
...isWebPlatform && combined ? { className: (0, import_core7.normalizeClassString)(combined) } : {},
|
|
4107
852
|
// Only attach state-tracking handlers when interactive modifiers are present.
|
|
4108
853
|
// Always forward user-provided handlers to avoid silently swallowing them.
|
|
4109
854
|
// Gated on isNative, not isWeb: isWeb is false during SSR too (no `window` there),
|
|
@@ -4118,7 +863,7 @@ function styled(Component, baseClasses = "") {
|
|
|
4118
863
|
// reliable signal either way. Forwarding them made React DOM warn "Unknown event
|
|
4119
864
|
// handler property" the moment any such component got an interactive modifier
|
|
4120
865
|
// (hover:, active:, …), which is the common case, not the exception.
|
|
4121
|
-
...!isNative ? hasInteractive ? {
|
|
866
|
+
...!import_core7.isNative ? hasInteractive ? {
|
|
4122
867
|
onPointerDown: handlePointerDown,
|
|
4123
868
|
onPointerUp: handlePointerUp,
|
|
4124
869
|
onPointerLeave: handlePointerLeave,
|
|
@@ -4142,58 +887,76 @@ function styled(Component, baseClasses = "") {
|
|
|
4142
887
|
}
|
|
4143
888
|
|
|
4144
889
|
// src/useStyles.ts
|
|
4145
|
-
var
|
|
890
|
+
var import_react7 = require("react");
|
|
891
|
+
var import_core8 = require("./core");
|
|
4146
892
|
function useStyles(classString, state = {}) {
|
|
4147
893
|
const { isDark, config } = useTheme();
|
|
4148
894
|
const width = useGlobalWidth();
|
|
4149
895
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
4150
|
-
return (0,
|
|
4151
|
-
const resolved = resolve(normalised, config.theme, config.darkMode);
|
|
4152
|
-
const breakpoints = getActiveBreakpoints(width);
|
|
4153
|
-
return flatten(resolved, isDark, state, breakpoints);
|
|
896
|
+
return (0, import_react7.useMemo)(() => {
|
|
897
|
+
const resolved = (0, import_core8.resolve)(normalised, config.theme, config.darkMode);
|
|
898
|
+
const breakpoints = (0, import_core8.getActiveBreakpoints)(width);
|
|
899
|
+
return (0, import_core8.flatten)(resolved, isDark, state, breakpoints);
|
|
4154
900
|
}, [normalised, isDark, config.theme, config.darkMode, width, state.hover, state.focus, state.pressed, state.active, state.disabled, state.checked, state.visited, state.placeholder]);
|
|
4155
901
|
}
|
|
4156
902
|
function useResolvedStyle(classString) {
|
|
4157
903
|
const { config } = useTheme();
|
|
4158
904
|
const normalised = Array.isArray(classString) ? classString.join(" ") : classString;
|
|
4159
|
-
return (0,
|
|
4160
|
-
() => resolve(normalised, config.theme, config.darkMode),
|
|
905
|
+
return (0, import_react7.useMemo)(
|
|
906
|
+
() => (0, import_core8.resolve)(normalised, config.theme, config.darkMode),
|
|
4161
907
|
[normalised, config]
|
|
4162
908
|
);
|
|
4163
909
|
}
|
|
4164
910
|
|
|
4165
911
|
// src/useBreakpoint.ts
|
|
4166
|
-
var
|
|
912
|
+
var import_react8 = require("react");
|
|
913
|
+
var import_core9 = require("./core");
|
|
914
|
+
function toNumericScreens(screens) {
|
|
915
|
+
const out = {};
|
|
916
|
+
for (const [name, v] of Object.entries(screens)) {
|
|
917
|
+
const n = typeof v === "number" ? v : parseInt(String(v), 10);
|
|
918
|
+
if (!Number.isNaN(n)) out[name] = n;
|
|
919
|
+
}
|
|
920
|
+
return out;
|
|
921
|
+
}
|
|
4167
922
|
function useBreakpoint() {
|
|
4168
923
|
const { config } = useTheme();
|
|
4169
924
|
const width = useGlobalWidth();
|
|
4170
925
|
const screens = config.theme.screens;
|
|
4171
|
-
const
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
926
|
+
const numericScreens = (0, import_react8.useMemo)(() => toNumericScreens(screens), [screens]);
|
|
927
|
+
return (0, import_react8.useMemo)(() => {
|
|
928
|
+
const active = (0, import_core9.getActiveBreakpoints)(width, numericScreens);
|
|
929
|
+
let best = null;
|
|
930
|
+
let bestMinW = -Infinity;
|
|
931
|
+
for (const name of active) {
|
|
932
|
+
const minW = numericScreens[name];
|
|
933
|
+
if (minW > bestMinW) {
|
|
934
|
+
bestMinW = minW;
|
|
935
|
+
best = name;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
return best ?? "xs";
|
|
939
|
+
}, [numericScreens, width]);
|
|
4179
940
|
}
|
|
4180
941
|
function useResponsive() {
|
|
4181
942
|
const { config } = useTheme();
|
|
4182
943
|
const width = useGlobalWidth();
|
|
4183
944
|
const screens = config.theme.screens;
|
|
4184
|
-
|
|
945
|
+
const numericScreens = (0, import_react8.useMemo)(() => toNumericScreens(screens), [screens]);
|
|
946
|
+
return (0, import_react8.useMemo)(() => {
|
|
947
|
+
const active = (0, import_core9.getActiveBreakpoints)(width, numericScreens);
|
|
4185
948
|
const result = {};
|
|
4186
|
-
for (const
|
|
4187
|
-
|
|
4188
|
-
if (!Number.isNaN(minW)) result[name] = width >= minW;
|
|
949
|
+
for (const name of Object.keys(numericScreens)) {
|
|
950
|
+
result[name] = active.has(name);
|
|
4189
951
|
}
|
|
4190
952
|
return result;
|
|
4191
|
-
}, [
|
|
953
|
+
}, [numericScreens, width]);
|
|
4192
954
|
}
|
|
4193
955
|
|
|
4194
956
|
// src/InteractiveWrapper.tsx
|
|
4195
|
-
var
|
|
4196
|
-
var
|
|
957
|
+
var import_react9 = __toESM(require("react"));
|
|
958
|
+
var import_core10 = require("./core");
|
|
959
|
+
var InteractiveWrapper = (0, import_react9.forwardRef)(
|
|
4197
960
|
function InteractiveWrapper2({
|
|
4198
961
|
Component,
|
|
4199
962
|
resolvedStyle,
|
|
@@ -4211,54 +974,55 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
4211
974
|
onBlur,
|
|
4212
975
|
...rest
|
|
4213
976
|
}, ref) {
|
|
4214
|
-
const isWebPlatform = getEffectiveIsWeb();
|
|
977
|
+
const isWebPlatform = (0, import_core10.getEffectiveIsWeb)();
|
|
4215
978
|
const isDark = useConditionalGlobalDarkMode(!isWebPlatform);
|
|
4216
979
|
const needsWidth = hasResponsiveBuckets(resolvedStyle);
|
|
4217
980
|
const width = useConditionalWidth(needsWidth && !isWebPlatform);
|
|
4218
|
-
const breakpoints = needsWidth ? getActiveBreakpoints(width) : EMPTY_BREAKPOINTS;
|
|
4219
|
-
const [pressed, setPressed] = (0,
|
|
4220
|
-
const [hovered, setHovered] = (0,
|
|
4221
|
-
const [focused, setFocused] = (0,
|
|
4222
|
-
const handlePressIn = (0,
|
|
981
|
+
const breakpoints = needsWidth ? (0, import_core10.getActiveBreakpoints)(width) : EMPTY_BREAKPOINTS;
|
|
982
|
+
const [pressed, setPressed] = (0, import_react9.useState)(false);
|
|
983
|
+
const [hovered, setHovered] = (0, import_react9.useState)(false);
|
|
984
|
+
const [focused, setFocused] = (0, import_react9.useState)(false);
|
|
985
|
+
const handlePressIn = (0, import_react9.useCallback)(chain(onPressIn, () => {
|
|
4223
986
|
if (!isWebPlatform) setPressed(true);
|
|
4224
987
|
}), [onPressIn, isWebPlatform]);
|
|
4225
|
-
const handlePressOut = (0,
|
|
988
|
+
const handlePressOut = (0, import_react9.useCallback)(chain(onPressOut, () => {
|
|
4226
989
|
if (!isWebPlatform) setPressed(false);
|
|
4227
990
|
}), [onPressOut, isWebPlatform]);
|
|
4228
|
-
const handlePointerDown = (0,
|
|
991
|
+
const handlePointerDown = (0, import_react9.useCallback)(chain(onPointerDown, () => {
|
|
4229
992
|
if (!isWebPlatform) setPressed(true);
|
|
4230
993
|
}), [onPointerDown, isWebPlatform]);
|
|
4231
|
-
const handlePointerUp = (0,
|
|
994
|
+
const handlePointerUp = (0, import_react9.useCallback)(chain(onPointerUp, () => {
|
|
4232
995
|
if (!isWebPlatform) setPressed(false);
|
|
4233
996
|
}), [onPointerUp, isWebPlatform]);
|
|
4234
|
-
const handlePointerLeave = (0,
|
|
997
|
+
const handlePointerLeave = (0, import_react9.useCallback)(chain(onPointerLeave, () => {
|
|
4235
998
|
if (!isWebPlatform) setPressed(false);
|
|
4236
999
|
}), [onPointerLeave, isWebPlatform]);
|
|
4237
|
-
const handlePointerCancel = (0,
|
|
1000
|
+
const handlePointerCancel = (0, import_react9.useCallback)(chain(onPointerCancel, () => {
|
|
4238
1001
|
if (!isWebPlatform) setPressed(false);
|
|
4239
1002
|
}), [onPointerCancel, isWebPlatform]);
|
|
4240
|
-
const handleMouseEnter = (0,
|
|
1003
|
+
const handleMouseEnter = (0, import_react9.useCallback)(chain(onMouseEnter, () => {
|
|
4241
1004
|
if (!isWebPlatform) setHovered(true);
|
|
4242
1005
|
}), [onMouseEnter, isWebPlatform]);
|
|
4243
|
-
const handleMouseLeave = (0,
|
|
1006
|
+
const handleMouseLeave = (0, import_react9.useCallback)(chain(onMouseLeave, () => {
|
|
4244
1007
|
if (!isWebPlatform) setHovered(false);
|
|
4245
1008
|
}), [onMouseLeave, isWebPlatform]);
|
|
4246
|
-
const handleFocus = (0,
|
|
1009
|
+
const handleFocus = (0, import_react9.useCallback)(chain(onFocus, () => {
|
|
4247
1010
|
if (!isWebPlatform) setFocused(true);
|
|
4248
1011
|
}), [onFocus, isWebPlatform]);
|
|
4249
|
-
const handleBlur = (0,
|
|
1012
|
+
const handleBlur = (0, import_react9.useCallback)(chain(onBlur, () => {
|
|
4250
1013
|
if (!isWebPlatform) setFocused(false);
|
|
4251
1014
|
}), [onBlur, isWebPlatform]);
|
|
4252
1015
|
const { children, disabled, checked, ...restForComponent } = rest;
|
|
4253
|
-
const
|
|
1016
|
+
const isNonStringComponent = typeof Component !== "string";
|
|
1017
|
+
const computedStyle = (0, import_react9.useMemo)(
|
|
4254
1018
|
() => {
|
|
4255
1019
|
if (isWebPlatform) return {};
|
|
4256
|
-
const s = flatten(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
|
|
1020
|
+
const s = (0, import_core10.flatten)(resolvedStyle, isDark, { pressed, hover: hovered, focus: focused, disabled: !!disabled, checked: !!checked }, breakpoints);
|
|
4257
1021
|
stripInternalMarkers(s);
|
|
4258
|
-
if (
|
|
1022
|
+
if (isNonStringComponent) stripWebOnlyProps(s);
|
|
4259
1023
|
return s;
|
|
4260
1024
|
},
|
|
4261
|
-
[resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked]
|
|
1025
|
+
[resolvedStyle, isDark, pressed, hovered, focused, width, disabled, checked, isNonStringComponent]
|
|
4262
1026
|
);
|
|
4263
1027
|
const skipComputedInline = isWebPlatform;
|
|
4264
1028
|
const finalStyle = skipComputedInline ? styleProp ?? void 0 : styleProp ? Array.isArray(styleProp) ? Object.assign({}, computedStyle, ...styleProp) : { ...computedStyle, ...styleProp } : computedStyle;
|
|
@@ -4268,7 +1032,7 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
4268
1032
|
...disabled !== void 0 ? { disabled } : {},
|
|
4269
1033
|
...checked !== void 0 ? { checked } : {},
|
|
4270
1034
|
style: finalStyle,
|
|
4271
|
-
...!isNative && className ? { className } : {},
|
|
1035
|
+
...!import_core10.isNative && className ? { className } : {},
|
|
4272
1036
|
// On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch) —
|
|
4273
1037
|
// onPressIn/onPressOut are RN-only prop names and are never forwarded here, even when
|
|
4274
1038
|
// Component isn't a literal HTML tag string. A non-string Component on web is just as
|
|
@@ -4282,7 +1046,7 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
4282
1046
|
// in jsx-runtime.tsx swaps it for a plain host tag — so keeping them pre-hydration would
|
|
4283
1047
|
// only have traded one prop-mismatch warning for another.) Genuinely native code paths
|
|
4284
1048
|
// still get them via the isNative branch below.
|
|
4285
|
-
...!isNative ? {
|
|
1049
|
+
...!import_core10.isNative ? {
|
|
4286
1050
|
onPointerDown: handlePointerDown,
|
|
4287
1051
|
onPointerUp: handlePointerUp,
|
|
4288
1052
|
onPointerLeave: handlePointerLeave,
|
|
@@ -4293,23 +1057,27 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
|
|
|
4293
1057
|
onFocus: handleFocus,
|
|
4294
1058
|
onBlur: handleBlur
|
|
4295
1059
|
};
|
|
4296
|
-
return Array.isArray(children) ?
|
|
1060
|
+
return Array.isArray(children) ? import_react9.default.createElement(Component, componentProps, ...children) : import_react9.default.createElement(Component, componentProps, children);
|
|
4297
1061
|
}
|
|
4298
1062
|
);
|
|
4299
1063
|
InteractiveWrapper.displayName = "Kbach.InteractiveWrapper";
|
|
4300
1064
|
|
|
4301
1065
|
// src/kb.ts
|
|
1066
|
+
var import_core11 = require("./core");
|
|
4302
1067
|
function kb(classString, isDark = false) {
|
|
4303
|
-
const config = getConfig();
|
|
4304
|
-
const resolved = resolve(classString, config.theme, config.darkMode);
|
|
4305
|
-
if (getEffectiveIsWeb()) {
|
|
1068
|
+
const config = (0, import_core11.getConfig)();
|
|
1069
|
+
const resolved = (0, import_core11.resolve)(classString, config.theme, config.darkMode);
|
|
1070
|
+
if ((0, import_core11.getEffectiveIsWeb)()) {
|
|
4306
1071
|
return classString;
|
|
4307
1072
|
}
|
|
4308
|
-
return flatten(resolved, isDark);
|
|
1073
|
+
return (0, import_core11.flatten)(resolved, isDark);
|
|
4309
1074
|
}
|
|
4310
1075
|
function cx(...classes) {
|
|
4311
1076
|
return classes.filter(Boolean).join(" ");
|
|
4312
1077
|
}
|
|
1078
|
+
|
|
1079
|
+
// src/index.ts
|
|
1080
|
+
var import_core12 = require("./core");
|
|
4313
1081
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4314
1082
|
0 && (module.exports = {
|
|
4315
1083
|
InteractiveWrapper,
|
|
@@ -4341,7 +1109,9 @@ function cx(...classes) {
|
|
|
4341
1109
|
useIsDark,
|
|
4342
1110
|
useResolvedStyle,
|
|
4343
1111
|
useResponsive,
|
|
1112
|
+
useSpacing,
|
|
4344
1113
|
useStyles,
|
|
4345
1114
|
useTheme,
|
|
4346
|
-
wrapColors
|
|
1115
|
+
wrapColors,
|
|
1116
|
+
wrapSpacing
|
|
4347
1117
|
});
|