@kbach/react-native 1.0.0-beta.30 → 1.0.0-beta.32

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.
@@ -10,13 +10,13 @@ import {
10
10
  subscribeDynamicTokens,
11
11
  subscribeGlobalDarkMode,
12
12
  toggleGlobalDarkMode
13
- } from "./chunk-LOTFFRZP.mjs";
13
+ } from "./chunk-XPVSILI4.mjs";
14
14
  import {
15
15
  defaultTheme,
16
16
  getTheme,
17
17
  resolveClassName,
18
18
  setTheme
19
- } from "./chunk-DDNGWPS4.mjs";
19
+ } from "./chunk-ZYE4VIZE.mjs";
20
20
 
21
21
  // src/config.ts
22
22
  function parseHexRgb(hex) {
@@ -180,59 +180,159 @@ var Evaluator = class {
180
180
  };
181
181
 
182
182
  // src/layoutCalc.ts
183
- var PERCENT_CALC_TOKEN_RE = /^(w|h)-\[calc\(([^)]+)\)\]$/;
183
+ var NEG = (v) => ({ percent: -v.percent, px: -v.px });
184
+ var ADD = (a, b) => ({ percent: a.percent + b.percent, px: a.px + b.px });
185
+ var SUB = (a, b) => ({ percent: a.percent - b.percent, px: a.px - b.px });
186
+ function MUL(a, b) {
187
+ if (a.percent === 0) return { percent: b.percent * a.px, px: b.px * a.px };
188
+ if (b.percent === 0) return { percent: a.percent * b.px, px: a.px * b.px };
189
+ return null;
190
+ }
191
+ function DIV(a, b) {
192
+ if (b.percent !== 0 || b.px === 0) return null;
193
+ return { percent: a.percent / b.px, px: a.px / b.px };
194
+ }
195
+ var PercentAwareEvaluator = class {
196
+ constructor(s) {
197
+ this.pos = 0;
198
+ this.s = s;
199
+ }
200
+ parseExprToEnd() {
201
+ const value = this.expr();
202
+ if (value === null) return null;
203
+ this.skipWs();
204
+ return this.pos === this.s.length ? value : null;
205
+ }
206
+ skipWs() {
207
+ while (this.pos < this.s.length && /\s/.test(this.s[this.pos])) this.pos++;
208
+ }
209
+ peek() {
210
+ this.skipWs();
211
+ return this.s[this.pos];
212
+ }
213
+ expr() {
214
+ let value = this.term();
215
+ if (value === null) return null;
216
+ for (; ; ) {
217
+ const ch = this.peek();
218
+ if (ch === "+") {
219
+ this.pos++;
220
+ const rhs = this.term();
221
+ if (rhs === null) return null;
222
+ value = ADD(value, rhs);
223
+ } else if (ch === "-") {
224
+ this.pos++;
225
+ const rhs = this.term();
226
+ if (rhs === null) return null;
227
+ value = SUB(value, rhs);
228
+ } else {
229
+ return value;
230
+ }
231
+ }
232
+ }
233
+ term() {
234
+ let value = this.factor();
235
+ if (value === null) return null;
236
+ for (; ; ) {
237
+ const ch = this.peek();
238
+ if (ch === "*") {
239
+ this.pos++;
240
+ const rhs = this.factor();
241
+ if (rhs === null) return null;
242
+ const result = MUL(value, rhs);
243
+ if (result === null) return null;
244
+ value = result;
245
+ } else if (ch === "/") {
246
+ this.pos++;
247
+ const rhs = this.factor();
248
+ if (rhs === null) return null;
249
+ const result = DIV(value, rhs);
250
+ if (result === null) return null;
251
+ value = result;
252
+ } else {
253
+ return value;
254
+ }
255
+ }
256
+ }
257
+ factor() {
258
+ const ch = this.peek();
259
+ if (ch === void 0) return null;
260
+ if (ch === "(") {
261
+ this.pos++;
262
+ const value = this.expr();
263
+ if (value === null || this.peek() !== ")") return null;
264
+ this.pos++;
265
+ return value;
266
+ }
267
+ if (ch === "-") {
268
+ this.pos++;
269
+ const value = this.factor();
270
+ return value === null ? null : NEG(value);
271
+ }
272
+ return this.numberWithUnit();
273
+ }
274
+ numberWithUnit() {
275
+ this.skipWs();
276
+ const start = this.pos;
277
+ while (this.pos < this.s.length && (/[0-9]/.test(this.s[this.pos]) || this.s[this.pos] === ".")) this.pos++;
278
+ if (this.pos === start) return null;
279
+ const n = Number(this.s.slice(start, this.pos));
280
+ if (!Number.isFinite(n)) return null;
281
+ if (this.s[this.pos] === "%") {
282
+ this.pos++;
283
+ return { percent: n, px: 0 };
284
+ }
285
+ const unitStart = this.pos;
286
+ while (this.pos < this.s.length && /[a-zA-Z]/.test(this.s[this.pos])) this.pos++;
287
+ const unit = this.s.slice(unitStart, this.pos);
288
+ switch (unit) {
289
+ case "":
290
+ return { percent: 0, px: n };
291
+ case "px":
292
+ return { percent: 0, px: n };
293
+ case "rem":
294
+ return { percent: 0, px: n * 16 };
295
+ default:
296
+ return null;
297
+ }
298
+ }
299
+ };
300
+ var PERCENT_TOKEN_OUTER_RE = /^(w|h)-\[(.+)\]$/;
184
301
  function parsePercentRelativeCalc(token) {
185
- const m = PERCENT_CALC_TOKEN_RE.exec(token);
302
+ const m = PERCENT_TOKEN_OUTER_RE.exec(token);
186
303
  if (!m) return null;
187
304
  const property = m[1] === "w" ? "width" : "height";
188
- const inner = m[2].replace(/_/g, " ").trim();
189
- let mm = /^(-?[\d.]+)%\s*([+-])\s*(.+)$/.exec(inner);
190
- if (mm) {
191
- const percentCoefficient = Number(mm[1]);
192
- const magnitude = reduceConstantMath(`calc(${mm[3].trim()})`);
193
- if (!Number.isFinite(percentCoefficient) || magnitude === null) return null;
194
- return { property, percentCoefficient, constantPx: mm[2] === "+" ? magnitude : -magnitude };
195
- }
196
- mm = /^(.+?)\s*([+-])\s*(-?[\d.]+)%$/.exec(inner);
197
- if (mm) {
198
- const constantPx = reduceConstantMath(`calc(${mm[1].trim()})`);
199
- const percentMagnitude = Number(mm[3]);
200
- if (constantPx === null || !Number.isFinite(percentMagnitude)) return null;
201
- return { property, percentCoefficient: mm[2] === "+" ? percentMagnitude : -percentMagnitude, constantPx };
202
- }
203
- return null;
305
+ const inner = stripCall(m[2].replace(/_/g, " ").trim(), "calc");
306
+ if (inner === null) return null;
307
+ const result = new PercentAwareEvaluator(inner).parseExprToEnd();
308
+ if (result === null || result.percent === 0) return null;
309
+ return { property, percentCoefficient: result.percent, constantPx: result.px };
204
310
  }
205
311
  function resolvePercentRelativeCalc(basisPx, calc) {
206
312
  return basisPx * calc.percentCoefficient / 100 + calc.constantPx;
207
313
  }
208
- var PERCENT_MIN_MAX_CLAMP_TOKEN_RE = /^(w|h)-\[(min|max|clamp)\(([^)]+)\)\]$/;
209
- function parseOperand(arg) {
210
- const trimmed = arg.trim();
211
- const pct = /^(-?[\d.]+)%$/.exec(trimmed);
212
- if (pct) {
213
- const percentCoefficient = Number(pct[1]);
214
- return Number.isFinite(percentCoefficient) ? { percentCoefficient, constantPx: 0 } : null;
215
- }
216
- const constantPx = reduceConstantMath(`calc(${trimmed})`);
217
- return constantPx === null ? null : { percentCoefficient: 0, constantPx };
218
- }
219
314
  function parsePercentRelativeMinMaxClamp(token) {
220
- const m = PERCENT_MIN_MAX_CLAMP_TOKEN_RE.exec(token);
315
+ const m = PERCENT_TOKEN_OUTER_RE.exec(token);
221
316
  if (!m) return null;
222
317
  const property = m[1] === "w" ? "width" : "height";
223
- const kind = m[2];
224
- const args = splitTopLevelCommas(m[3].replace(/_/g, " "));
318
+ const spaced = m[2].replace(/_/g, " ");
319
+ let kind;
320
+ let inner;
321
+ if ((inner = stripCall(spaced, "min")) !== null) kind = "min";
322
+ else if ((inner = stripCall(spaced, "max")) !== null) kind = "max";
323
+ else if ((inner = stripCall(spaced, "clamp")) !== null) kind = "clamp";
324
+ else return null;
325
+ const args = splitTopLevelCommas(inner);
225
326
  if (kind === "clamp" && args.length !== 3) return null;
226
327
  if (kind !== "clamp" && args.length < 1) return null;
227
- const operands = args.map(parseOperand);
328
+ const operands = args.map((arg) => new PercentAwareEvaluator(arg.trim()).parseExprToEnd());
228
329
  if (operands.some((o) => o === null)) return null;
229
330
  const resolved = operands;
230
- if (!resolved.some((o) => o.percentCoefficient !== 0)) return null;
231
- const resolveOperand = (o, basisPx) => basisPx * o.percentCoefficient / 100 + o.constantPx;
331
+ if (!resolved.some((o) => o.percent !== 0)) return null;
232
332
  return {
233
333
  property,
234
334
  resolve(basisPx) {
235
- const values = resolved.map((o) => resolveOperand(o, basisPx));
335
+ const values = resolved.map((o) => basisPx * o.percent / 100 + o.px);
236
336
  if (kind === "min") return Math.min(...values);
237
337
  if (kind === "max") return Math.max(...values);
238
338
  const [min, preferred, max] = values;
@@ -420,6 +520,63 @@ var ARBITRARY_PROPERTY_SENTINEL = "[arbitrary-property]";
420
520
  function isSafeArbitraryValue(value) {
421
521
  return !value.includes("{") && !value.includes("}") && !value.includes(";");
422
522
  }
523
+ function normalizeMathWhitespace(raw) {
524
+ if (!(raw.startsWith("calc(") || raw.startsWith("min(") || raw.startsWith("max(") || raw.startsWith("clamp("))) {
525
+ return raw;
526
+ }
527
+ const chars = Array.from(raw);
528
+ let out = "";
529
+ let i = 0;
530
+ let prevEndsValue = false;
531
+ while (i < chars.length) {
532
+ const c = chars[i];
533
+ if (c === "v" && chars[i + 1] === "a" && chars[i + 2] === "r" && chars[i + 3] === "(") {
534
+ const start = i;
535
+ let depth = 0;
536
+ while (i < chars.length) {
537
+ if (chars[i] === "(") depth++;
538
+ else if (chars[i] === ")") {
539
+ depth--;
540
+ if (depth === 0) {
541
+ i++;
542
+ break;
543
+ }
544
+ }
545
+ i++;
546
+ }
547
+ out += chars.slice(start, i).join("");
548
+ prevEndsValue = true;
549
+ continue;
550
+ }
551
+ if (c === "+" || c === "-") {
552
+ if (prevEndsValue) {
553
+ out += ` ${c} `;
554
+ i++;
555
+ while (i < chars.length && /\s/.test(chars[i])) i++;
556
+ prevEndsValue = false;
557
+ continue;
558
+ }
559
+ out += c;
560
+ prevEndsValue = false;
561
+ } else if (c === "(" || c === ",") {
562
+ out += c;
563
+ if (c === ",") out += " ";
564
+ prevEndsValue = false;
565
+ } else if (c === ")") {
566
+ out += c;
567
+ prevEndsValue = true;
568
+ } else if (/\s/.test(c)) {
569
+ } else if (c === "*" || c === "/") {
570
+ out += c;
571
+ prevEndsValue = false;
572
+ } else {
573
+ out += c;
574
+ prevEndsValue = true;
575
+ }
576
+ i++;
577
+ }
578
+ return out;
579
+ }
423
580
  function splitRespectingBrackets(token) {
424
581
  const parts = [];
425
582
  let depth = 0;
@@ -455,7 +612,7 @@ function parseClass(token) {
455
612
  const property = raw.slice(0, colonIdx);
456
613
  const rawValue = raw.slice(colonIdx + 1);
457
614
  if (property !== "" && rawValue !== "" && isSafeArbitraryValue(raw)) {
458
- const value = rawValue.replace(/_/g, " ");
615
+ const value = normalizeMathWhitespace(rawValue.replace(/_/g, " "));
459
616
  return {
460
617
  modifiers,
461
618
  utility: ARBITRARY_PROPERTY_SENTINEL,
@@ -477,7 +634,7 @@ function parseClass(token) {
477
634
  if (!isSafeArbitraryValue(raw)) {
478
635
  continue;
479
636
  }
480
- const spaced = raw.replace(/_/g, " ");
637
+ const spaced = normalizeMathWhitespace(raw.replace(/_/g, " "));
481
638
  return {
482
639
  modifiers,
483
640
  utility: prefix.slice(0, -1),
@@ -518,7 +675,7 @@ function substituteDynamicTokens(classStrRaw) {
518
675
  return value ?? whole;
519
676
  });
520
677
  }
521
- var PERCENT_RELATIVE_CALC_HINT_RE = /[wh]-\[(calc|min|max|clamp)\([^)]*%[^)]*\)\]/;
678
+ var PERCENT_RELATIVE_CALC_HINT_RE = /[wh]-\[(calc|min|max|clamp)\(.*%.*\)\]/;
522
679
  function extractPercentRelativeCalcs(classStrRaw) {
523
680
  const found = [];
524
681
  for (const token of classStrRaw.split(/\s+/)) {
@@ -531,26 +688,64 @@ function stripPercentRelativeCalcTokens(classStrRaw) {
531
688
  return classStrRaw.split(/\s+/).filter((token) => token && parsePercentRelativeExpr(token) === null).join(" ");
532
689
  }
533
690
  var STATE_MODIFIER_NAMES = /* @__PURE__ */ new Set(["hover", "focus", "disabled"]);
534
- var STATE_MODIFIER_HINT_RE = /(^|\s|:)(hover|focus|disabled):/;
691
+ var STATIC_ARIA_SHORTCUT_NAMES = /* @__PURE__ */ new Set([
692
+ "aria-checked",
693
+ "aria-disabled",
694
+ "aria-expanded",
695
+ "aria-hidden",
696
+ "aria-pressed",
697
+ "aria-readonly",
698
+ "aria-required",
699
+ "aria-selected",
700
+ "aria-busy"
701
+ ]);
702
+ var STATE_MODIFIER_HINT_RE = /(^|\s|:)(hover|focus|disabled|aria-checked|aria-disabled|aria-expanded|aria-hidden|aria-pressed|aria-readonly|aria-required|aria-selected|aria-busy):|data-\[|aria-\[/;
703
+ function bracketContent(name, prefix) {
704
+ if (!name.startsWith(prefix)) return null;
705
+ const rest = name.slice(prefix.length);
706
+ if (!rest.startsWith("[") || !rest.endsWith("]")) return null;
707
+ return rest.slice(1, -1);
708
+ }
709
+ function evalAttrCondition(hostRest, attrPrefix, inner) {
710
+ const eqIdx = inner.indexOf("=");
711
+ if (eqIdx === -1) return Boolean(hostRest[`${attrPrefix}${inner}`]);
712
+ const key = inner.slice(0, eqIdx);
713
+ const value = inner.slice(eqIdx + 1);
714
+ return String(hostRest[`${attrPrefix}${key}`]) === value;
715
+ }
716
+ function isAriaTruthy(value) {
717
+ return value === true || value === "true";
718
+ }
719
+ function propBasedModifierState(name, states, hostRest) {
720
+ if (STATE_MODIFIER_NAMES.has(name)) return states[name];
721
+ if (STATIC_ARIA_SHORTCUT_NAMES.has(name)) return isAriaTruthy(hostRest[name]);
722
+ const dataInner = bracketContent(name, "data-");
723
+ if (dataInner !== null) return evalAttrCondition(hostRest, "data-", dataInner);
724
+ const ariaInner = bracketContent(name, "aria-");
725
+ if (ariaInner !== null) return evalAttrCondition(hostRest, "aria-", ariaInner);
726
+ return null;
727
+ }
535
728
  function stripModifiers(parts, namesToStrip) {
536
729
  const utility = parts[parts.length - 1] ?? "";
537
730
  const modifiers = parts.slice(0, -1).filter((m) => !namesToStrip.has(m));
538
731
  return [...modifiers, utility].join(":");
539
732
  }
540
- function substituteStateModifiers(classStrRaw, states) {
733
+ function substituteStateModifiers(classStrRaw, states, hostRest) {
541
734
  if (!STATE_MODIFIER_HINT_RE.test(classStrRaw)) return classStrRaw;
542
735
  const kept = [];
543
736
  for (const token of classStrRaw.split(/\s+/)) {
544
737
  if (!token) continue;
545
738
  const parts = splitRespectingBrackets(token);
546
739
  const modifiers = parts.slice(0, -1);
547
- const required = modifiers.filter((m) => STATE_MODIFIER_NAMES.has(m));
740
+ const resolved = modifiers.map((m) => [m, propBasedModifierState(m, states, hostRest)]);
741
+ const required = resolved.filter(([, v]) => v !== null);
548
742
  if (required.length === 0) {
549
743
  kept.push(token);
550
744
  continue;
551
745
  }
552
- if (required.every((m) => states[m])) {
553
- kept.push(stripModifiers(parts, STATE_MODIFIER_NAMES));
746
+ if (required.every(([, v]) => v === true)) {
747
+ const requiredNames = new Set(required.map(([m]) => m));
748
+ kept.push(stripModifiers(parts, requiredNames));
554
749
  }
555
750
  }
556
751
  return kept.join(" ");
@@ -558,8 +753,8 @@ function substituteStateModifiers(classStrRaw, states) {
558
753
  function makeElement(isStaticChildren, type, props, key) {
559
754
  return (isStaticChildren ? import_jsx_runtime.jsxs : import_jsx_runtime.jsx)(type, props, key);
560
755
  }
561
- function resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, pressed, layoutOverrides, states = { hover: false, focus: false, disabled: false }) {
562
- const stateResolved = substituteStateModifiers(classStrRaw, states);
756
+ function resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, pressed, hostRest, layoutOverrides, states = { hover: false, focus: false, disabled: false }) {
757
+ const stateResolved = substituteStateModifiers(classStrRaw, states, hostRest);
563
758
  const cleaned = stripPercentRelativeCalcTokens(substituteDynamicTokens(stateResolved));
564
759
  const resolved = resolveStyle2(cleaned, pressed);
565
760
  if (layoutOverrides) {
@@ -574,7 +769,7 @@ function resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, pressed, layout
574
769
  return [resolved, userStyle];
575
770
  }
576
771
  var DARK_MODIFIER_RE = /(^|\s|:)dark:/;
577
- var BREAKPOINT_MODIFIER_RE = /(^|\s|:)(sm|md|lg|xl|2xl):/;
772
+ var BREAKPOINT_MODIFIER_RE = /(^|\s|:)(sm|md|lg|xl|2xl):|(^|\s|:)(min|max)-\[[^\]]*\]:/;
578
773
  var HOVER_MODIFIER_RE = /(^|\s|:)hover:/;
579
774
  var FOCUS_MODIFIER_RE = /(^|\s|:)focus:/;
580
775
  function ReactiveElement({
@@ -652,7 +847,7 @@ function ReactiveElement({
652
847
  };
653
848
  }
654
849
  const states = { hover: isHovered, focus: isFocused, disabled: hostRest.disabled === true };
655
- const finalStyle = hostType === import_react_native.Pressable ? (state) => resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, state.pressed, layoutOverrides, states) : resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, false, layoutOverrides, states);
850
+ const finalStyle = hostType === import_react_native.Pressable ? (state) => resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, state.pressed, hostRest, layoutOverrides, states) : resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, false, hostRest, layoutOverrides, states);
656
851
  return makeElement(
657
852
  isStaticChildren,
658
853
  hostType,
@@ -676,7 +871,7 @@ function processElement(resolveStyle2, type, rawProps, key, isStaticChildren) {
676
871
  );
677
872
  }
678
873
  const staticStates = { hover: false, focus: false, disabled: rest.disabled === true };
679
- const finalStyle = type === import_react_native.Pressable ? (state) => resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, state.pressed, void 0, staticStates) : resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, false, void 0, staticStates);
874
+ const finalStyle = type === import_react_native.Pressable ? (state) => resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, state.pressed, rest, void 0, staticStates) : resolvedStyleFor(resolveStyle2, classStrRaw, userStyle, false, rest, void 0, staticStates);
680
875
  return makeElement(isStaticChildren, type, { ...rest, className: classStrRaw, style: finalStyle }, key);
681
876
  }
682
877
  function createJsxFunctions(resolveStyle2) {
@@ -1778,6 +1973,14 @@ function nativeModifierState(modifier, theme, colorScheme, pressed, width) {
1778
1973
  if (minWidth === void 0) return null;
1779
1974
  return width >= minWidth;
1780
1975
  }
1976
+ if (modifier.startsWith("min-[") && modifier.endsWith("]")) {
1977
+ const px = reduceConstantMath(`calc(${modifier.slice(5, -1).trim()})`);
1978
+ return px === null ? null : width >= px;
1979
+ }
1980
+ if (modifier.startsWith("max-[") && modifier.endsWith("]")) {
1981
+ const px = reduceConstantMath(`calc(${modifier.slice(5, -1).trim()})`);
1982
+ return px === null ? null : width <= px;
1983
+ }
1781
1984
  return null;
1782
1985
  }
1783
1986
  function kebabToCamel(s) {