@william-callao/antonella-ui 1.0.4 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +124 -13
  2. package/dist/index.js +671 -477
  3. package/package.json +7 -3
package/dist/index.js CHANGED
@@ -148,10 +148,13 @@ __export(index_exports, {
148
148
  hasCode: () => hasCode,
149
149
  hostDirection: () => hostDirection,
150
150
  iconMap: () => iconMap,
151
+ isLayoutDebug: () => isLayoutDebug,
152
+ layoutDebug: () => layoutDebug,
151
153
  layoutStates: () => layoutStates,
152
154
  removeNode: () => removeNode,
153
155
  resolveComposition: () => resolveComposition,
154
156
  resolveTransition: () => resolveTransition,
157
+ setLayoutDebug: () => setLayoutDebug,
155
158
  updateNode: () => updateNode,
156
159
  useAppNavigation: () => useAppNavigation,
157
160
  useAppShell: () => useAppShell,
@@ -1656,19 +1659,27 @@ function SheetOverlay({
1656
1659
  document.body.style.overflow = previousOverflow;
1657
1660
  };
1658
1661
  }, [embedded, mounted, dismissible, onClose]);
1659
- const overlay = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native22.View, { style: styles21.container, pointerEvents: embedded ? "box-none" : void 0, children: [
1660
- !embedded && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1661
- import_react_native22.Pressable,
1662
- {
1663
- onPress: dismissible ? onClose : void 0,
1664
- style: import_react_native22.StyleSheet.absoluteFill,
1665
- accessibilityRole: "button",
1666
- accessibilityLabel,
1667
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_reanimated3.default.View, { style: [styles21.backdrop, backdropStyle] })
1668
- }
1669
- ),
1670
- children
1671
- ] });
1662
+ const overlay = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1663
+ import_react_native22.View,
1664
+ {
1665
+ style: styles21.container,
1666
+ pointerEvents: embedded ? "box-none" : void 0,
1667
+ accessibilityViewIsModal: embedded,
1668
+ children: [
1669
+ !embedded && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1670
+ import_react_native22.Pressable,
1671
+ {
1672
+ onPress: dismissible ? onClose : void 0,
1673
+ style: import_react_native22.StyleSheet.absoluteFill,
1674
+ accessibilityRole: "button",
1675
+ accessibilityLabel,
1676
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_reanimated3.default.View, { style: [styles21.backdrop, backdropStyle] })
1677
+ }
1678
+ ),
1679
+ children
1680
+ ]
1681
+ }
1682
+ );
1672
1683
  if (embedded) {
1673
1684
  return overlay;
1674
1685
  }
@@ -3897,7 +3908,7 @@ var PALETTE_GROUPS = [
3897
3908
  colors: Object.entries(import_antonella_theme38.danger).map(([label, value]) => ({ label, value }))
3898
3909
  }
3899
3910
  ];
3900
- var ALL_COLORS = PALETTE_GROUPS.flatMap((g) => g.colors);
3911
+ var ALL_COLORS = PALETTE_GROUPS.flatMap((g2) => g2.colors);
3901
3912
  function findTokenLabel(hex) {
3902
3913
  const upper = normalizeHex(hex);
3903
3914
  const match = ALL_COLORS.find((c) => c.value.toUpperCase() === upper);
@@ -4520,6 +4531,7 @@ function ProductCard({
4520
4531
  price,
4521
4532
  code,
4522
4533
  cart,
4534
+ maxQuantity,
4523
4535
  onQuantityChange,
4524
4536
  imageIcon = "camera",
4525
4537
  style = "DEFAULT" /* DEFAULT */,
@@ -4529,9 +4541,13 @@ function ProductCard({
4529
4541
  const [quantity, setQuantity] = (0, import_react15.useState)(cart?.quantity ?? 0);
4530
4542
  const [editing, setEditing] = (0, import_react15.useState)(false);
4531
4543
  const [draft, setDraft] = (0, import_react15.useState)(String(cart?.quantity ?? 0));
4544
+ const hasMax = maxQuantity != null && Number.isFinite(maxQuantity);
4545
+ const max = hasMax ? Math.max(0, Math.floor(maxQuantity)) : 0;
4546
+ const atMax = hasMax && quantity >= max;
4532
4547
  const commitQuantity = () => {
4533
4548
  const parsed = Number.parseInt(draft, 10);
4534
- const next = Number.isNaN(parsed) || parsed < 0 ? 0 : parsed;
4549
+ const raw = Number.isNaN(parsed) || parsed < 0 ? 0 : parsed;
4550
+ const next = hasMax ? Math.min(raw, max) : raw;
4535
4551
  setQuantity(next);
4536
4552
  setDraft(String(next));
4537
4553
  setEditing(false);
@@ -4608,6 +4624,7 @@ function ProductCard({
4608
4624
  import_react_native45.Pressable,
4609
4625
  {
4610
4626
  onPress: () => {
4627
+ if (atMax) return;
4611
4628
  const q = quantity + 1;
4612
4629
  setQuantity(q);
4613
4630
  setDraft(String(q));
@@ -4616,10 +4633,12 @@ function ProductCard({
4616
4633
  style: ({ pressed }) => [
4617
4634
  styles41.stepperButton,
4618
4635
  { backgroundColor: ctx.bg.subtle },
4619
- pressed && styles41.stepperButtonPressed
4636
+ pressed && styles41.stepperButtonPressed,
4637
+ atMax && styles41.stepperButtonDisabled
4620
4638
  ],
4621
4639
  accessibilityRole: "button",
4622
4640
  accessibilityLabel: "Aumentar cantidad",
4641
+ accessibilityState: { disabled: atMax },
4623
4642
  children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: "add", size: 16, color: import_antonella_theme42.cta1 })
4624
4643
  }
4625
4644
  )
@@ -4631,12 +4650,18 @@ function ProductCard({
4631
4650
  setDraft("1");
4632
4651
  onQuantityChange?.(1);
4633
4652
  },
4634
- style: [styles41.addButton, { backgroundColor: ctx.bg.default }],
4653
+ disabled: hasMax && max <= 0,
4654
+ style: ({ pressed }) => [
4655
+ styles41.addButton,
4656
+ { backgroundColor: ctx.bg.default },
4657
+ hasMax && max <= 0 ? styles41.addButtonDisabled : pressed && styles41.stepperButtonPressed
4658
+ ],
4635
4659
  accessibilityRole: "button",
4636
4660
  accessibilityLabel: "A\xF1adir al carrito",
4661
+ accessibilityState: { disabled: hasMax && max <= 0 },
4637
4662
  children: [
4638
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: "add", size: 16, color: import_antonella_theme42.cta1 }),
4639
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { variant: import_antonella_theme42.TextType.Caption, color: import_antonella_theme42.cta1, children: "A\xF1adir" })
4663
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: "add", size: 16, color: hasMax && max <= 0 ? ctx.text.subtle : import_antonella_theme42.cta1 }),
4664
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { variant: import_antonella_theme42.TextType.Caption, color: hasMax && max <= 0 ? ctx.text.subtle : import_antonella_theme42.cta1, children: "A\xF1adir" })
4640
4665
  ]
4641
4666
  }
4642
4667
  ) })
@@ -4720,6 +4745,9 @@ var styles41 = import_react_native45.StyleSheet.create({
4720
4745
  stepperButtonPressed: {
4721
4746
  opacity: 0.6
4722
4747
  },
4748
+ stepperButtonDisabled: {
4749
+ opacity: 0.35
4750
+ },
4723
4751
  addButton: {
4724
4752
  flexDirection: "row",
4725
4753
  alignItems: "center",
@@ -4728,6 +4756,9 @@ var styles41 = import_react_native45.StyleSheet.create({
4728
4756
  paddingVertical: import_antonella_theme42.space.space2,
4729
4757
  borderRadius: 999
4730
4758
  },
4759
+ addButtonDisabled: {
4760
+ opacity: 0.5
4761
+ },
4731
4762
  quantity: {
4732
4763
  minWidth: 32,
4733
4764
  textAlign: "center"
@@ -4775,6 +4806,8 @@ function ElementCard({
4775
4806
  onPress,
4776
4807
  trailing = "chevron-forward",
4777
4808
  onTrailingPress,
4809
+ trailingLabel,
4810
+ trailingAccessibilityLabel,
4778
4811
  dimmed = false,
4779
4812
  style = "DEFAULT" /* DEFAULT */,
4780
4813
  containerStyle,
@@ -4823,6 +4856,7 @@ function ElementCard({
4823
4856
  onPress: onTrailingPress,
4824
4857
  hitSlop: 8,
4825
4858
  accessibilityRole: "button",
4859
+ accessibilityLabel: trailingLabel ?? trailingAccessibilityLabel,
4826
4860
  style: styles42.trailingTouch,
4827
4861
  children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: trailing, size: 18, color: ctx.icon.subtle })
4828
4862
  }
@@ -5286,28 +5320,28 @@ function buildSolidLUT(color) {
5286
5320
  var Z_BUCKETS = 1024;
5287
5321
  function recordPicture(buf, size, lut, rMin) {
5288
5322
  "worklet";
5289
- const g = globalThis;
5290
- let paint = g.__expoThinkingOrbsPaint;
5323
+ const g2 = globalThis;
5324
+ let paint = g2.__expoThinkingOrbsPaint;
5291
5325
  if (paint === void 0) {
5292
5326
  paint = import_react_native_skia.Skia.Paint();
5293
5327
  paint.setAntiAlias(true);
5294
- g.__expoThinkingOrbsPaint = paint;
5328
+ g2.__expoThinkingOrbsPaint = paint;
5295
5329
  }
5296
5330
  const n = buf.count;
5297
5331
  const zs = buf.zs;
5298
- let order = g.__expoThinkingOrbsOrder;
5299
- let bucket = g.__expoThinkingOrbsBucket;
5332
+ let order = g2.__expoThinkingOrbsOrder;
5333
+ let bucket = g2.__expoThinkingOrbsBucket;
5300
5334
  if (order === void 0 || order.length < n) {
5301
5335
  order = new Int32Array(n);
5302
5336
  bucket = new Int32Array(n);
5303
- g.__expoThinkingOrbsOrder = order;
5304
- g.__expoThinkingOrbsBucket = bucket;
5337
+ g2.__expoThinkingOrbsOrder = order;
5338
+ g2.__expoThinkingOrbsBucket = bucket;
5305
5339
  }
5306
5340
  const buckets = bucket;
5307
- let counts = g.__expoThinkingOrbsCounts;
5341
+ let counts = g2.__expoThinkingOrbsCounts;
5308
5342
  if (counts === void 0) {
5309
5343
  counts = new Int32Array(Z_BUCKETS);
5310
- g.__expoThinkingOrbsCounts = counts;
5344
+ g2.__expoThinkingOrbsCounts = counts;
5311
5345
  } else {
5312
5346
  counts.fill(0);
5313
5347
  }
@@ -5331,11 +5365,11 @@ function recordPicture(buf, size, lut, rMin) {
5331
5365
  running += c;
5332
5366
  }
5333
5367
  for (let i = 0; i < n; i++) order[counts[buckets[i]]++] = i;
5334
- let rect = g.__expoThinkingOrbsRect;
5335
- if (rect === void 0 || g.__expoThinkingOrbsRectSize !== size) {
5368
+ let rect = g2.__expoThinkingOrbsRect;
5369
+ if (rect === void 0 || g2.__expoThinkingOrbsRectSize !== size) {
5336
5370
  rect = import_react_native_skia.Skia.XYWHRect(0, 0, size, size);
5337
- g.__expoThinkingOrbsRect = rect;
5338
- g.__expoThinkingOrbsRectSize = size;
5371
+ g2.__expoThinkingOrbsRect = rect;
5372
+ g2.__expoThinkingOrbsRectSize = size;
5339
5373
  }
5340
5374
  const rec = import_react_native_skia.Skia.PictureRecorder();
5341
5375
  const canvas = rec.beginRecording(rect);
@@ -5363,11 +5397,11 @@ function recordPicture(buf, size, lut, rMin) {
5363
5397
  // src/components/ComposingOrb/engine/scratch.ts
5364
5398
  function acquireDynamics(amp, from, to, mix, yaw = 0, pitch = 0, roll = 0) {
5365
5399
  "worklet";
5366
- const g = globalThis;
5367
- let d = g.__expoThinkingOrbsDyn;
5400
+ const g2 = globalThis;
5401
+ let d = g2.__expoThinkingOrbsDyn;
5368
5402
  if (d === void 0) {
5369
5403
  d = { amp, from, to, mix, yaw, pitch, roll };
5370
- g.__expoThinkingOrbsDyn = d;
5404
+ g2.__expoThinkingOrbsDyn = d;
5371
5405
  return d;
5372
5406
  }
5373
5407
  d.amp = amp;
@@ -5381,8 +5415,8 @@ function acquireDynamics(amp, from, to, mix, yaw = 0, pitch = 0, roll = 0) {
5381
5415
  }
5382
5416
  function acquireDotBuffer(capacity) {
5383
5417
  "worklet";
5384
- const g = globalThis;
5385
- let buf = g.__expoThinkingOrbsScratch;
5418
+ const g2 = globalThis;
5419
+ let buf = g2.__expoThinkingOrbsScratch;
5386
5420
  if (buf === void 0 || buf.capacity < capacity) {
5387
5421
  buf = {
5388
5422
  xs: new Float32Array(capacity),
@@ -5394,7 +5428,7 @@ function acquireDotBuffer(capacity) {
5394
5428
  count: 0,
5395
5429
  capacity
5396
5430
  };
5397
- g.__expoThinkingOrbsScratch = buf;
5431
+ g2.__expoThinkingOrbsScratch = buf;
5398
5432
  }
5399
5433
  buf.count = 0;
5400
5434
  return buf;
@@ -7113,27 +7147,40 @@ var TreeNodeItem = import_react27.default.memo(function TreeNodeItem2({
7113
7147
  ) : null
7114
7148
  ] })
7115
7149
  ] });
7150
+ const canToggle = hasChildren;
7151
+ const canOpenDetail = !hasChildren && ctx.onPressNode != null;
7152
+ const canOpenActions = ctx.isEdit;
7153
+ const interactive = canToggle || canOpenDetail || canOpenActions;
7154
+ const handlePress = canToggle ? () => ctx.onToggle(node.id) : canOpenDetail ? () => ctx.onPressNode?.(node) : void 0;
7155
+ const handleLongPress = ctx.isEdit ? () => ctx.onOpenActions(node.id) : void 0;
7116
7156
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
7117
7157
  /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_react_native63.View, { style: styles57.nodeRow, children: [
7118
7158
  /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(NodeGutter, { depth, lineColor: ctx.vt.lineColor, terminal: terminalElbow }),
7119
7159
  /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
7120
7160
  import_react_native63.Pressable,
7121
7161
  {
7122
- onPress: hasChildren ? () => ctx.onToggle(node.id) : void 0,
7123
- disabled: !hasChildren,
7162
+ onPress: handlePress,
7163
+ onLongPress: handleLongPress,
7164
+ delayLongPress: 450,
7165
+ disabled: !interactive,
7124
7166
  style: ({ pressed }) => [
7125
7167
  styles57.nodeCard,
7126
7168
  {
7127
7169
  backgroundColor: pressed ? isActive ? ctx.vt.activePressedBg : ctx.vt.pressedBg : isActive ? ctx.vt.activeCardBg : ctx.vt.cardBg
7128
7170
  }
7129
7171
  ],
7130
- accessibilityRole: hasChildren ? "button" : void 0,
7172
+ accessibilityRole: interactive ? "button" : void 0,
7131
7173
  accessibilityState: hasChildren ? { expanded: !isCollapsed } : void 0,
7132
- accessibilityLabel: hasChildren ? `${isCollapsed ? "Expandir" : "Colapsar"} ${node.name}` : void 0,
7174
+ accessibilityLabel: hasChildren ? `${isCollapsed ? "Expandir" : "Colapsar"} ${node.name}` : canOpenDetail ? `${node.name}, ver detalle` : void 0,
7175
+ accessibilityHint: ctx.isEdit ? "Manten\xE9 presionado para ver las acciones" : void 0,
7176
+ accessibilityActions: ctx.isEdit ? [{ name: "actions", label: "Acciones" }] : void 0,
7177
+ onAccessibilityAction: (event) => {
7178
+ if (event.nativeEvent.actionName === "actions") ctx.onOpenActions(node.id);
7179
+ },
7133
7180
  children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react_native63.View, { style: styles57.rowContent, children: ctx.renderNode ? ctx.renderNode(node, defaultContent) : defaultContent })
7134
7181
  }
7135
7182
  ),
7136
- ctx.isEdit ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
7183
+ ctx.isEdit && !ctx.actionsOnLongPress ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
7137
7184
  import_react_native63.Pressable,
7138
7185
  {
7139
7186
  onPress: () => ctx.onOpenActions(node.id),
@@ -7148,7 +7195,7 @@ var TreeNodeItem = import_react27.default.memo(function TreeNodeItem2({
7148
7195
  hasChildren && !isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_react_native63.Animated.View, { style: [styles57.subtreeFade, { opacity: contentOpacity }], children: renderForest(ctx, node.children, depth + 1, node.name) }) : null
7149
7196
  ] });
7150
7197
  });
7151
- function TreeEditor({ value, onChange, mode = "view", variant = "default", collapsed: collapsedProp, onCollapsedChange, rootLabel = "Agregar ra\xEDz", renderNode, onRequestAdd, onRequestEdit, onRequestDelete, style }) {
7198
+ function TreeEditor({ value, onChange, mode = "view", variant = "default", collapsed: collapsedProp, onCollapsedChange, rootLabel = "Agregar ra\xEDz", renderNode, onRequestAdd, onRequestEdit, onRequestDelete, nodeActions = "menu", onPressNode, style }) {
7152
7199
  const [internalCollapsed, setInternalCollapsed] = (0, import_react27.useState)({});
7153
7200
  const source = collapsedProp ?? internalCollapsed;
7154
7201
  const needsImplicitInit = value.length > 0 && Object.keys(source).length === 0;
@@ -7214,6 +7261,7 @@ function TreeEditor({ value, onChange, mode = "view", variant = "default", colla
7214
7261
  }, [implicitInit]);
7215
7262
  const vt = VARIANT_TOKENS[variant];
7216
7263
  const isEdit = mode === "edit";
7264
+ const actionsOnLongPress = nodeActions === "longPress";
7217
7265
  const getCollapsed = (0, import_react27.useCallback)(() => collapsedRef.current, []);
7218
7266
  const getVersion = (0, import_react27.useCallback)((id) => versionRef.current.get(id) ?? 0, []);
7219
7267
  const toggleCollapse = (0, import_react27.useCallback)((id) => {
@@ -7241,14 +7289,16 @@ function TreeEditor({ value, onChange, mode = "view", variant = "default", colla
7241
7289
  const ctx = (0, import_react27.useMemo)(
7242
7290
  () => ({
7243
7291
  isEdit,
7292
+ actionsOnLongPress,
7244
7293
  onToggle: toggleCollapse,
7245
7294
  onOpenActions,
7295
+ onPressNode,
7246
7296
  renderNode,
7247
7297
  vt,
7248
7298
  getCollapsed,
7249
7299
  getVersion
7250
7300
  }),
7251
- [isEdit, toggleCollapse, onOpenActions, renderNode, vt, getCollapsed, getVersion]
7301
+ [isEdit, actionsOnLongPress, toggleCollapse, onOpenActions, onPressNode, renderNode, vt, getCollapsed, getVersion]
7252
7302
  );
7253
7303
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
7254
7304
  import_react_native63.View,
@@ -7284,6 +7334,10 @@ var styles57 = import_react_native63.StyleSheet.create({
7284
7334
  alignItems: "center",
7285
7335
  gap: import_antonella_theme59.space.space1,
7286
7336
  minHeight: 44,
7337
+ // No dejar que el CTA de alta se comprima a altura cero cuando el árbol es
7338
+ // largo y el contenedor queda acotado (APP-002: "Agregar raíz" degeneraba a
7339
+ // bounds con y1 == y2 y dejaba de ser accionable).
7340
+ flexShrink: 0,
7287
7341
  paddingHorizontal: import_antonella_theme59.space.space2,
7288
7342
  borderRadius: import_antonella_theme59.radius.sm
7289
7343
  },
@@ -7441,9 +7495,9 @@ var import_jsx_runtime66 = require("react/jsx-runtime");
7441
7495
  function contrast(hex) {
7442
7496
  const h = hex.replace("#", "");
7443
7497
  const r = parseInt(h.substring(0, 2), 16);
7444
- const g = parseInt(h.substring(2, 4), 16);
7498
+ const g2 = parseInt(h.substring(2, 4), 16);
7445
7499
  const b = parseInt(h.substring(4, 6), 16);
7446
- return (r * 299 + g * 587 + b * 114) / 1e3 > 150 ? "#1C1C1E" : "#FFFFFF";
7500
+ return (r * 299 + g2 * 587 + b * 114) / 1e3 > 150 ? "#1C1C1E" : "#FFFFFF";
7447
7501
  }
7448
7502
  function SplitColorCard({
7449
7503
  label,
@@ -7627,6 +7681,7 @@ var SINGLE_LINE_HEIGHT = 18;
7627
7681
  function AppTextInput({
7628
7682
  label,
7629
7683
  labelWidth,
7684
+ error,
7630
7685
  value,
7631
7686
  onChangeText,
7632
7687
  placeholder,
@@ -7650,77 +7705,83 @@ function AppTextInput({
7650
7705
  const handleSubmitEditing = () => {
7651
7706
  inputRef.current?.blur();
7652
7707
  };
7653
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
7654
- import_react_native67.TouchableOpacity,
7655
- {
7656
- style: [
7657
- styles61.row,
7658
- inputHeight != null && inputHeight > SINGLE_LINE_HEIGHT && styles61.rowGrown,
7659
- !editable && styles61.rowDisabled
7660
- ],
7661
- onPress: () => onPressOverride ? onPressOverride() : focus(),
7662
- disabled: !editable && !readOnly,
7663
- activeOpacity: 1,
7664
- children: [
7665
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
7666
- Text,
7667
- {
7668
- variant: import_antonella_theme62.TextType.Label,
7669
- numberOfLines: 1,
7670
- style: [styles61.label, labelWidth != null && { width: labelWidth }],
7671
- children: label
7672
- }
7673
- ),
7674
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
7675
- import_react_native67.TextInput,
7676
- {
7677
- ref: inputRef,
7678
- style: [
7679
- styles61.value,
7680
- {
7681
- fontSize: import_antonella_theme62.texts.caption.fontSize,
7682
- lineHeight: import_antonella_theme62.texts.caption.lineHeight,
7683
- color: import_antonella_theme62.text.default
7684
- },
7685
- inputHeight != null && {
7686
- height: Math.max(inputHeight, SINGLE_LINE_HEIGHT)
7687
- }
7688
- ],
7689
- value,
7690
- onChangeText,
7691
- onContentSizeChange: handleContentSizeChange,
7692
- onSubmitEditing: handleSubmitEditing,
7693
- placeholder,
7694
- placeholderTextColor: import_antonella_theme62.texts.placeholder.color,
7695
- autoCapitalize,
7696
- keyboardType,
7697
- maxLength,
7698
- editable: canType,
7699
- selectionColor: import_antonella_theme62.text.default,
7700
- underlineColorAndroid: "transparent",
7701
- multiline: true,
7702
- scrollEnabled: false,
7703
- textAlignVertical: "top",
7704
- blurOnSubmit: true,
7705
- submitBehavior: "blurAndSubmit"
7706
- }
7707
- ),
7708
- trailingAction ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
7709
- import_react_native67.Pressable,
7710
- {
7711
- onPress: trailingAction.onPress,
7712
- hitSlop: 8,
7713
- style: styles61.trailingAction,
7714
- accessibilityRole: "button",
7715
- accessibilityLabel: trailingAction.accessibilityLabel,
7716
- children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Icon, { name: trailingAction.icon, size: 20, color: import_antonella_theme62.text.secondary })
7717
- }
7718
- ) : null
7719
- ]
7720
- }
7721
- );
7708
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_react_native67.View, { style: styles61.wrapper, children: [
7709
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
7710
+ import_react_native67.TouchableOpacity,
7711
+ {
7712
+ style: [
7713
+ styles61.row,
7714
+ inputHeight != null && inputHeight > SINGLE_LINE_HEIGHT && styles61.rowGrown,
7715
+ !editable && styles61.rowDisabled
7716
+ ],
7717
+ onPress: () => onPressOverride ? onPressOverride() : focus(),
7718
+ disabled: !editable && !readOnly,
7719
+ activeOpacity: 1,
7720
+ children: [
7721
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
7722
+ Text,
7723
+ {
7724
+ variant: import_antonella_theme62.TextType.Label,
7725
+ numberOfLines: 1,
7726
+ style: [styles61.label, labelWidth != null && { width: labelWidth }],
7727
+ children: label
7728
+ }
7729
+ ),
7730
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
7731
+ import_react_native67.TextInput,
7732
+ {
7733
+ ref: inputRef,
7734
+ style: [
7735
+ styles61.value,
7736
+ {
7737
+ fontSize: import_antonella_theme62.texts.caption.fontSize,
7738
+ lineHeight: import_antonella_theme62.texts.caption.lineHeight,
7739
+ color: import_antonella_theme62.text.default
7740
+ },
7741
+ inputHeight != null && {
7742
+ height: Math.max(inputHeight, SINGLE_LINE_HEIGHT)
7743
+ }
7744
+ ],
7745
+ value,
7746
+ onChangeText,
7747
+ onContentSizeChange: handleContentSizeChange,
7748
+ onSubmitEditing: handleSubmitEditing,
7749
+ placeholder,
7750
+ placeholderTextColor: import_antonella_theme62.texts.placeholder.color,
7751
+ autoCapitalize,
7752
+ keyboardType,
7753
+ maxLength,
7754
+ editable: canType,
7755
+ selectionColor: import_antonella_theme62.text.default,
7756
+ underlineColorAndroid: "transparent",
7757
+ multiline: true,
7758
+ scrollEnabled: false,
7759
+ textAlignVertical: "top",
7760
+ blurOnSubmit: true,
7761
+ submitBehavior: "blurAndSubmit"
7762
+ }
7763
+ ),
7764
+ trailingAction ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
7765
+ import_react_native67.Pressable,
7766
+ {
7767
+ onPress: trailingAction.onPress,
7768
+ hitSlop: 8,
7769
+ style: styles61.trailingAction,
7770
+ accessibilityRole: "button",
7771
+ accessibilityLabel: trailingAction.accessibilityLabel,
7772
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Icon, { name: trailingAction.icon, size: 20, color: import_antonella_theme62.text.secondary })
7773
+ }
7774
+ ) : null
7775
+ ]
7776
+ }
7777
+ ),
7778
+ error ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Text, { variant: import_antonella_theme62.TextType.Caption, color: import_antonella_theme62.appInput.error, style: styles61.error, children: error }) : null
7779
+ ] });
7722
7780
  }
7723
7781
  var styles61 = import_react_native67.StyleSheet.create({
7782
+ wrapper: {
7783
+ alignItems: "stretch"
7784
+ },
7724
7785
  row: {
7725
7786
  flexDirection: "row",
7726
7787
  alignItems: "center",
@@ -7749,6 +7810,11 @@ var styles61 = import_react_native67.StyleSheet.create({
7749
7810
  trailingAction: {
7750
7811
  marginLeft: import_antonella_theme62.spacing.xs,
7751
7812
  justifyContent: "center"
7813
+ },
7814
+ error: {
7815
+ marginTop: import_antonella_theme62.spacing.xs,
7816
+ paddingHorizontal: import_antonella_theme62.space.space4,
7817
+ textAlign: "right"
7752
7818
  }
7753
7819
  });
7754
7820
 
@@ -7761,6 +7827,7 @@ var SINGLE_LINE_HEIGHT2 = 18;
7761
7827
  var MIN_AREA_HEIGHT = 72;
7762
7828
  function AppTextArea({
7763
7829
  label,
7830
+ error,
7764
7831
  value,
7765
7832
  onChangeText,
7766
7833
  placeholder,
@@ -7780,58 +7847,64 @@ function AppTextArea({
7780
7847
  const handleSubmitEditing = () => {
7781
7848
  inputRef.current?.blur();
7782
7849
  };
7783
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
7784
- import_react_native68.TouchableOpacity,
7785
- {
7786
- style: [
7787
- styles62.container,
7788
- inputHeight != null && inputHeight > SINGLE_LINE_HEIGHT2 && styles62.containerGrown,
7789
- !editable && styles62.containerDisabled
7790
- ],
7791
- onPress: focus,
7792
- disabled: !editable,
7793
- activeOpacity: 1,
7794
- children: [
7795
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Text, { variant: import_antonella_theme63.TextType.Label, numberOfLines: 1, style: styles62.label, children: label }),
7796
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
7797
- import_react_native68.TextInput,
7798
- {
7799
- ref: inputRef,
7800
- style: [
7801
- styles62.value,
7802
- {
7803
- fontSize: import_antonella_theme63.texts.caption.fontSize,
7804
- lineHeight: import_antonella_theme63.texts.caption.lineHeight,
7805
- color: import_antonella_theme63.text.default
7806
- },
7807
- inputHeight != null && {
7808
- height: Math.max(inputHeight, SINGLE_LINE_HEIGHT2)
7809
- }
7810
- ],
7811
- value,
7812
- onChangeText,
7813
- onContentSizeChange: handleContentSizeChange,
7814
- onSubmitEditing: handleSubmitEditing,
7815
- placeholder,
7816
- placeholderTextColor: import_antonella_theme63.texts.placeholder.color,
7817
- autoCapitalize,
7818
- keyboardType,
7819
- maxLength,
7820
- editable,
7821
- selectionColor: import_antonella_theme63.text.default,
7822
- underlineColorAndroid: "transparent",
7823
- multiline: true,
7824
- scrollEnabled: false,
7825
- textAlignVertical: "top",
7826
- blurOnSubmit: true,
7827
- submitBehavior: "blurAndSubmit"
7828
- }
7829
- )
7830
- ]
7831
- }
7832
- );
7850
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_react_native68.View, { style: styles62.wrapper, children: [
7851
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
7852
+ import_react_native68.TouchableOpacity,
7853
+ {
7854
+ style: [
7855
+ styles62.container,
7856
+ inputHeight != null && inputHeight > SINGLE_LINE_HEIGHT2 && styles62.containerGrown,
7857
+ !editable && styles62.containerDisabled
7858
+ ],
7859
+ onPress: focus,
7860
+ disabled: !editable,
7861
+ activeOpacity: 1,
7862
+ children: [
7863
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Text, { variant: import_antonella_theme63.TextType.Label, numberOfLines: 1, style: styles62.label, children: label }),
7864
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
7865
+ import_react_native68.TextInput,
7866
+ {
7867
+ ref: inputRef,
7868
+ style: [
7869
+ styles62.value,
7870
+ {
7871
+ fontSize: import_antonella_theme63.texts.caption.fontSize,
7872
+ lineHeight: import_antonella_theme63.texts.caption.lineHeight,
7873
+ color: import_antonella_theme63.text.default
7874
+ },
7875
+ inputHeight != null && {
7876
+ height: Math.max(inputHeight, SINGLE_LINE_HEIGHT2)
7877
+ }
7878
+ ],
7879
+ value,
7880
+ onChangeText,
7881
+ onContentSizeChange: handleContentSizeChange,
7882
+ onSubmitEditing: handleSubmitEditing,
7883
+ placeholder,
7884
+ placeholderTextColor: import_antonella_theme63.texts.placeholder.color,
7885
+ autoCapitalize,
7886
+ keyboardType,
7887
+ maxLength,
7888
+ editable,
7889
+ selectionColor: import_antonella_theme63.text.default,
7890
+ underlineColorAndroid: "transparent",
7891
+ multiline: true,
7892
+ scrollEnabled: false,
7893
+ textAlignVertical: "top",
7894
+ blurOnSubmit: true,
7895
+ submitBehavior: "blurAndSubmit"
7896
+ }
7897
+ )
7898
+ ]
7899
+ }
7900
+ ),
7901
+ error ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Text, { variant: import_antonella_theme63.TextType.Caption, color: import_antonella_theme63.appInput.error, style: styles62.error, children: error }) : null
7902
+ ] });
7833
7903
  }
7834
7904
  var styles62 = import_react_native68.StyleSheet.create({
7905
+ wrapper: {
7906
+ alignItems: "stretch"
7907
+ },
7835
7908
  container: {
7836
7909
  gap: import_antonella_theme63.space.space2,
7837
7910
  minHeight: MIN_AREA_HEIGHT,
@@ -7854,6 +7927,12 @@ var styles62 = import_react_native68.StyleSheet.create({
7854
7927
  paddingRight: 2,
7855
7928
  textAlign: "left",
7856
7929
  outlineWidth: 0
7930
+ },
7931
+ error: {
7932
+ marginTop: import_antonella_theme63.spacing.xs,
7933
+ paddingHorizontal: import_antonella_theme63.space.space4,
7934
+ paddingBottom: import_antonella_theme63.spacing.sm,
7935
+ textAlign: "left"
7857
7936
  }
7858
7937
  });
7859
7938
 
@@ -7868,6 +7947,7 @@ var ANIM_DURATION2 = 220;
7868
7947
  function AppSelector({
7869
7948
  label,
7870
7949
  labelWidth,
7950
+ error,
7871
7951
  value,
7872
7952
  onChange,
7873
7953
  options,
@@ -7911,6 +7991,7 @@ function AppSelector({
7911
7991
  }, [open, contentHeight, options.length, height, contentOpacity]);
7912
7992
  const toggle = () => {
7913
7993
  if (disabled) return;
7994
+ if (!open) import_react_native69.Keyboard.dismiss();
7914
7995
  setOpen((o) => !o);
7915
7996
  };
7916
7997
  const handleSelect = (option) => {
@@ -7951,6 +8032,7 @@ function AppSelector({
7951
8032
  ]
7952
8033
  }
7953
8034
  ),
8035
+ error ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Text, { variant: import_antonella_theme64.TextType.Caption, color: import_antonella_theme64.appInput.error, style: styles63.error, children: error }) : null,
7954
8036
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_react_native69.Animated.View, { style: { height, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
7955
8037
  import_react_native69.Animated.View,
7956
8038
  {
@@ -8021,6 +8103,12 @@ var styles63 = import_react_native69.StyleSheet.create({
8021
8103
  borderTopWidth: import_react_native69.StyleSheet.hairlineWidth,
8022
8104
  borderTopColor: import_antonella_theme64.appInputCard.separator
8023
8105
  },
8106
+ error: {
8107
+ marginTop: -import_antonella_theme64.spacing.sm,
8108
+ paddingHorizontal: import_antonella_theme64.space.space4,
8109
+ paddingBottom: import_antonella_theme64.spacing.sm,
8110
+ textAlign: "right"
8111
+ },
8024
8112
  optionText: {
8025
8113
  flex: 1
8026
8114
  }
@@ -8150,12 +8238,14 @@ function AppButton({
8150
8238
  label,
8151
8239
  onPress,
8152
8240
  disabled = false,
8241
+ loading = false,
8153
8242
  variant = "solid",
8154
8243
  backgroundColor,
8155
8244
  textColor,
8156
8245
  borderColor,
8157
8246
  style
8158
8247
  }) {
8248
+ const interactiveDisabled = disabled || loading;
8159
8249
  const background15 = disabled ? import_antonella_theme66.appButton.background.disabled : backgroundColor ?? (variant === "solid" ? import_antonella_theme66.appButton.background.default : "transparent");
8160
8250
  const foreground = disabled ? import_antonella_theme66.appButton.text.disabled : textColor ?? (variant === "solid" ? import_antonella_theme66.appButton.text.default : import_antonella_theme66.text.default);
8161
8251
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
@@ -8175,19 +8265,14 @@ function AppButton({
8175
8265
  style
8176
8266
  ],
8177
8267
  onPress,
8178
- disabled,
8268
+ disabled: interactiveDisabled,
8179
8269
  activeOpacity: 0.7,
8180
8270
  accessibilityRole: "button",
8181
- accessibilityState: { disabled },
8182
- children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
8183
- Text,
8184
- {
8185
- variant: "label",
8186
- color: foreground,
8187
- style: styles65.label,
8188
- children: label
8189
- }
8190
- )
8271
+ accessibilityState: { disabled: interactiveDisabled, busy: loading },
8272
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_react_native71.View, { style: styles65.content, children: [
8273
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Text, { variant: "label", color: foreground, style: styles65.label, children: label }),
8274
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(import_react_native71.ActivityIndicator, { size: "small", color: foreground, style: styles65.spinner }) : null
8275
+ ] })
8191
8276
  }
8192
8277
  );
8193
8278
  }
@@ -8200,8 +8285,16 @@ var styles65 = import_react_native71.StyleSheet.create({
8200
8285
  alignItems: "center",
8201
8286
  justifyContent: "center"
8202
8287
  },
8288
+ content: {
8289
+ flexDirection: "row",
8290
+ alignItems: "center",
8291
+ justifyContent: "center"
8292
+ },
8203
8293
  label: {
8204
8294
  textAlign: "center"
8295
+ },
8296
+ spinner: {
8297
+ marginLeft: import_antonella_theme66.space.space2
8205
8298
  }
8206
8299
  });
8207
8300
 
@@ -8677,7 +8770,6 @@ var styles69 = import_react_native75.StyleSheet.create({
8677
8770
  // src/layout/AppLayout.tsx
8678
8771
  var import_react35 = require("react");
8679
8772
  var import_react_native77 = require("react-native");
8680
- var import_react_native78 = require("react-native");
8681
8773
  var import_react_native_reanimated16 = __toESM(require("react-native-reanimated"));
8682
8774
 
8683
8775
  // src/layout/Divisor.tsx
@@ -8741,12 +8833,62 @@ var styles70 = import_react_native76.StyleSheet.create({
8741
8833
  }
8742
8834
  });
8743
8835
 
8744
- // src/layout/AppLayout.tsx
8836
+ // src/layout/layoutDebug.ts
8837
+ var RING_MAX = 400;
8838
+ function g() {
8839
+ return globalThis;
8840
+ }
8841
+ function ring() {
8842
+ const global = g();
8843
+ global.__ANTONELLA_LAYOUT_LOG__ ??= [];
8844
+ return global.__ANTONELLA_LAYOUT_LOG__;
8845
+ }
8846
+ var envFlag = typeof process !== "undefined" && process.env ? String(process.env.EXPO_PUBLIC_LAYOUT_DEBUG ?? "").toLowerCase() : "";
8847
+ var forced = envFlag === "1" || envFlag === "true";
8848
+ function setLayoutDebug(on) {
8849
+ forced = on;
8850
+ if (on) {
8851
+ console.log("[APPLAYOUT] debug ON");
8852
+ }
8853
+ }
8854
+ function isLayoutDebug() {
8855
+ return forced;
8856
+ }
8857
+ function layoutDebug(event, data) {
8858
+ const entry = { t: Date.now(), event, data };
8859
+ const buffer = ring();
8860
+ buffer.push(entry);
8861
+ if (buffer.length > RING_MAX) {
8862
+ buffer.splice(0, buffer.length - RING_MAX);
8863
+ }
8864
+ if (forced) {
8865
+ console.log(`[APPLAYOUT ${event}]`, data ? JSON.stringify(data) : "");
8866
+ }
8867
+ }
8868
+ if (typeof globalThis !== "undefined") {
8869
+ const global = g();
8870
+ global.__ANTONELLA_LAYOUT_DEBUG__ = setLayoutDebug;
8871
+ global.__ANTONELLA_LAYOUT_DUMP__ = () => {
8872
+ const buffer = ring().slice();
8873
+ console.log(`[APPLAYOUT] ${buffer.length} eventos`);
8874
+ console.log(JSON.stringify(buffer, null, 2));
8875
+ return buffer;
8876
+ };
8877
+ }
8878
+
8879
+ // src/layout/layoutMath.ts
8745
8880
  var import_antonella_theme71 = require("@william-callao/antonella-theme");
8746
- var import_jsx_runtime78 = require("react/jsx-runtime");
8881
+ var SECTION_KEYS = ["top", "mid", "bottom"];
8747
8882
  var _semantic12 = (0, import_antonella_theme71.resolveSemantic)(import_antonella_theme71.lightSemantic);
8748
8883
  var DEFAULT_BG2 = _semantic12.default.bg.default;
8749
8884
  var DARK_BG = _semantic12.darkness.bg.default;
8885
+ var SECTION_DEFAULT_COLORS = {
8886
+ top: DARK_BG,
8887
+ mid: DEFAULT_BG2,
8888
+ bottom: DARK_BG
8889
+ };
8890
+ var DEFAULT_PAGE_BG = DEFAULT_BG2;
8891
+ var FULLBOTTOM_DIVISOR_H = 25;
8750
8892
  var layoutStates = {
8751
8893
  stacked: {
8752
8894
  pageScroll: false,
@@ -8795,25 +8937,83 @@ var layoutStates = {
8795
8937
  }
8796
8938
  }
8797
8939
  };
8798
- var SECTION_KEYS = ["top", "mid", "bottom"];
8799
- var DEFAULT_COLORS = {
8800
- top: DARK_BG,
8801
- mid: DEFAULT_BG2,
8802
- bottom: DARK_BG
8803
- };
8940
+ function resolveLayoutState(state, presets = layoutStates) {
8941
+ return typeof state === "string" ? presets[state] : state;
8942
+ }
8943
+ function isValidMeasurement(height) {
8944
+ return Number.isFinite(height) && height > 0;
8945
+ }
8946
+ function initialNaturals(H) {
8947
+ return { top: H / 3, mid: H / 3, bottom: H / 3 };
8948
+ }
8949
+ function bottomViewport(state, naturals, H) {
8950
+ const anchor = state.sections.bottom?.restsOn;
8951
+ if (!anchor) return H;
8952
+ const rest = H - naturals[anchor];
8953
+ return rest > 0 ? rest : H;
8954
+ }
8955
+ function bottomOverflows(state, naturals, H) {
8956
+ const b = state.sections.bottom;
8957
+ if (!b?.visible) return false;
8958
+ return naturals.bottom > bottomViewport(state, naturals, H);
8959
+ }
8960
+ function computeSectionTargets(state, naturals, H) {
8961
+ const out = { top: 0, mid: 0, bottom: 0 };
8962
+ for (const k of SECTION_KEYS) {
8963
+ const b = state.sections[k];
8964
+ if (!b?.visible) {
8965
+ out[k] = 0;
8966
+ continue;
8967
+ }
8968
+ const h = b.height ?? "content";
8969
+ if (h === "content") out[k] = naturals[k];
8970
+ else if (h === "third") out[k] = H / 3;
8971
+ else if (h === "fill") out[k] = H;
8972
+ else if (h === "fillRest") out[k] = b.restsOn ? H - naturals[b.restsOn] : 0;
8973
+ else if (h === "minFillRest") {
8974
+ const rest = b.restsOn ? H - naturals[b.restsOn] : 0;
8975
+ out[k] = Math.max(naturals[k], rest);
8976
+ } else out[k] = h;
8977
+ }
8978
+ const fullBottom = !state.sections.top?.visible && !state.sections.mid?.visible;
8979
+ if (fullBottom && state.sections.bottom?.visible) {
8980
+ out.bottom = Math.max(0, out.bottom - FULLBOTTOM_DIVISOR_H);
8981
+ }
8982
+ return out;
8983
+ }
8984
+ function selectPageBackground(state, colors = SECTION_DEFAULT_COLORS) {
8985
+ const mid = state.sections.mid;
8986
+ if (mid?.visible) {
8987
+ return mid.backgroundColor ?? colors.mid;
8988
+ }
8989
+ for (let i = SECTION_KEYS.length - 1; i >= 0; i--) {
8990
+ const k = SECTION_KEYS[i];
8991
+ if (state.sections[k]?.visible) {
8992
+ return state.sections[k]?.backgroundColor ?? colors[k];
8993
+ }
8994
+ }
8995
+ return DEFAULT_PAGE_BG;
8996
+ }
8997
+ function shouldResetScroll(prevRouteName, nextRouteName) {
8998
+ return prevRouteName !== nextRouteName;
8999
+ }
9000
+ function seedNaturals(snapshot, routeName, neutral) {
9001
+ const snap = snapshot.get(routeName);
9002
+ return snap ? { ...snap } : { ...neutral };
9003
+ }
9004
+ function writeNaturals(snapshot, routeName, naturals) {
9005
+ snapshot.set(routeName, { ...naturals });
9006
+ }
9007
+
9008
+ // src/layout/AppLayout.tsx
9009
+ var import_jsx_runtime78 = require("react/jsx-runtime");
8804
9010
  var LAYOUT_DURATION = 300;
8805
9011
  var REVEAL_DELAY_MS = 380;
8806
9012
  var REVEAL_DURATION_MS = 200;
8807
- var REMOUNT_WINDOW_MS = 500;
8808
- var BODY_TAIL = 600;
8809
- var FULLBOTTOM_DIVISOR_H = 25;
8810
- var FULLBOTTOM_OVERSCAN = 5;
8811
- var FULLBOTTOM_EXTEND = 5;
8812
- var FULLBOTTOM_CUSHION = 5;
8813
- var _withBottomHold = (t, cur) => {
8814
- const held = t.bottom < cur.bottom ? cur.bottom : t.bottom;
8815
- return held === t.bottom ? t : { ...t, bottom: held };
8816
- };
9013
+ var PROBE_INTERVAL_MS = 150;
9014
+ var PROBE_STABLE_HITS = 2;
9015
+ var PROBE_MAX_MS = 4e3;
9016
+ var _sanitize = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
8817
9017
  var AppNavigationContext = (0, import_react35.createContext)(null);
8818
9018
  function useAppNavigation() {
8819
9019
  const ctx = (0, import_react35.useContext)(AppNavigationContext);
@@ -8826,9 +9026,12 @@ function AppLayout({
8826
9026
  initialRoute,
8827
9027
  showBackButton = true,
8828
9028
  animateTransitions = false,
8829
- contentReveal = "always"
9029
+ contentReveal = "always",
9030
+ debug = false
8830
9031
  }) {
8831
- const { height: H } = (0, import_react_native78.useWindowDimensions)();
9032
+ const { height: H } = (0, import_react_native77.useWindowDimensions)();
9033
+ const HRef = (0, import_react35.useRef)(H);
9034
+ HRef.current = H;
8832
9035
  const reduceMotion = (0, import_react_native_reanimated16.useReducedMotion)();
8833
9036
  const transition2 = reduceMotion ? import_react_native_reanimated16.LinearTransition.duration(0) : import_react_native_reanimated16.CurvedTransition.duration(LAYOUT_DURATION);
8834
9037
  const revealProgress = (0, import_react_native_reanimated16.useSharedValue)(1);
@@ -8836,6 +9039,13 @@ function AppLayout({
8836
9039
  const [stack, setStack] = (0, import_react35.useState)([initialRoute]);
8837
9040
  const [prevRoute, setPrevRoute] = (0, import_react35.useState)(null);
8838
9041
  const hasTransition = animateTransitions && prevRoute !== null;
9042
+ const initialNaturalsValue = (0, import_react35.useRef)(initialNaturals(H)).current;
9043
+ const [layoutHeights, setLayoutHeights] = (0, import_react35.useState)(
9044
+ () => computeSectionTargets(resolveLayoutState(initialRoute.state), initialNaturalsValue, H)
9045
+ );
9046
+ const appliedRef = (0, import_react35.useRef)(layoutHeights);
9047
+ const naturalsRef = (0, import_react35.useRef)({ ...initialNaturalsValue });
9048
+ const routeSnapshotRef = (0, import_react35.useRef)(/* @__PURE__ */ new Map());
8839
9049
  const [revealHidden, setRevealHidden] = (0, import_react35.useState)(false);
8840
9050
  const revealTimer = (0, import_react35.useRef)(null);
8841
9051
  const startReveal = (0, import_react35.useCallback)(() => {
@@ -8848,11 +9058,27 @@ function AppLayout({
8848
9058
  revealProgress.value = (0, import_react_native_reanimated16.withTiming)(1, { duration: REVEAL_DURATION_MS });
8849
9059
  setRevealHidden(false);
8850
9060
  }, REVEAL_DELAY_MS);
8851
- }, [revealProgress, REVEAL_DELAY_MS, REVEAL_DURATION_MS]);
9061
+ }, [revealProgress]);
9062
+ const stateRef = (0, import_react35.useRef)(layoutStates.onlyCenter);
9063
+ const currentRouteNameRef = (0, import_react35.useRef)(initialRoute.name);
9064
+ const bodyOverflowRef = (0, import_react35.useRef)(false);
9065
+ const [pageCanScroll, setPageCanScroll] = (0, import_react35.useState)(false);
9066
+ const scrollRef = (0, import_react35.useRef)(null);
9067
+ const innerScrollRef = (0, import_react35.useRef)(null);
9068
+ const proxyRefs = (0, import_react35.useRef)({});
9069
+ const probeTimers = (0, import_react35.useRef)({});
9070
+ const probeLast = (0, import_react35.useRef)({});
9071
+ const probeStable = (0, import_react35.useRef)({});
9072
+ (0, import_react35.useEffect)(() => {
9073
+ if (debug) setLayoutDebug(true);
9074
+ }, [debug]);
8852
9075
  (0, import_react35.useEffect)(() => {
8853
9076
  return () => {
8854
9077
  if (revealTimer.current) clearTimeout(revealTimer.current);
8855
- if (settleTimer.current) clearTimeout(settleTimer.current);
9078
+ SECTION_KEYS.forEach((k) => {
9079
+ const t = probeTimers.current[k];
9080
+ if (t) clearInterval(t);
9081
+ });
8856
9082
  };
8857
9083
  }, []);
8858
9084
  (0, import_react35.useEffect)(() => {
@@ -8893,137 +9119,143 @@ function AppLayout({
8893
9119
  stack,
8894
9120
  replace
8895
9121
  };
8896
- const resolvedState = typeof currentRoute.state === "string" ? layoutStates[currentRoute.state] : currentRoute.state;
8897
- const state = resolvedState ?? layoutStates.onlyCenter;
9122
+ const state = resolveLayoutState(currentRoute.state);
8898
9123
  const slots = currentRoute.slots ?? {};
8899
- const prevLayoutState = prevRoute ? typeof prevRoute.state === "string" ? layoutStates[prevRoute.state] : prevRoute.state : null;
8900
- const pageBg = DEFAULT_BG2;
9124
+ stateRef.current = state;
9125
+ const prevLayoutState = prevRoute ? resolveLayoutState(prevRoute.state) : null;
9126
+ const pageBg = selectPageBackground(state);
8901
9127
  const topVisible = !!state.sections.top?.visible;
8902
9128
  const midVisible = !!state.sections.mid?.visible;
8903
9129
  const bottomVisible = !!state.sections.bottom?.visible;
8904
9130
  const showTopDivisor = topVisible && (midVisible || bottomVisible);
8905
9131
  const showBottomDivisor = bottomVisible && (topVisible || midVisible);
8906
9132
  const showFullBottomDivisor = bottomVisible && !topVisible && !midVisible;
8907
- const [layoutHeights, setLayoutHeights] = (0, import_react35.useState)({
8908
- top: H / 3,
8909
- mid: H / 3,
8910
- bottom: H / 3
8911
- });
8912
- const layoutHeightsRef = (0, import_react35.useRef)(layoutHeights);
8913
- layoutHeightsRef.current = layoutHeights;
8914
- const stateRef = (0, import_react35.useRef)(state);
8915
- stateRef.current = state;
8916
- const bodyOverflowRef = (0, import_react35.useRef)(false);
8917
- const [pageCanScroll, setPageCanScroll] = (0, import_react35.useState)(false);
8918
- const settleTimer = (0, import_react35.useRef)(null);
8919
- const scrollRef = (0, import_react35.useRef)(null);
8920
- const innerScrollRef = (0, import_react35.useRef)(null);
8921
- const rootViewRef = (0, import_react35.useRef)(null);
8922
- const capHolderRef = (0, import_react35.useRef)(null);
8923
- const naturalsRef = (0, import_react35.useRef)({
8924
- top: H / 3,
8925
- mid: H / 3,
8926
- bottom: H / 3
8927
- });
8928
- const lastMeasured = (0, import_react35.useRef)({ top: 0, mid: 0, bottom: 0 });
8929
- const routeChangedAt = (0, import_react35.useRef)(0);
8930
- const computeTargets = (st) => {
8931
- const base = { top: 0, mid: 0, bottom: 0 };
8932
- for (const k of SECTION_KEYS) {
8933
- const b = st.sections[k];
8934
- if (!b?.visible) {
8935
- base[k] = 0;
8936
- continue;
8937
- }
8938
- const h = b.height ?? "content";
8939
- if (h === "content") base[k] = naturalsRef.current[k];
8940
- else if (h === "third") base[k] = H / 3;
8941
- else if (h === "fill") base[k] = H;
8942
- else if (h === "fillRest") base[k] = b.restsOn ? H - naturalsRef.current[b.restsOn] : 0;
8943
- else if (h === "minFillRest") {
8944
- const rest = b.restsOn ? H - naturalsRef.current[b.restsOn] : 0;
8945
- base[k] = Math.max(naturalsRef.current[k], rest);
8946
- } else base[k] = h;
8947
- }
8948
- return base;
8949
- };
8950
- const bottomViewport = () => {
8951
- const b = stateRef.current.sections.bottom;
8952
- if (!b?.restsOn) return H;
8953
- const rest = H - naturalsRef.current[b.restsOn];
8954
- return rest > 0 ? rest : H;
8955
- };
9133
+ const computeTargets = (0, import_react35.useCallback)(
9134
+ (st) => computeSectionTargets(st, naturalsRef.current, HRef.current),
9135
+ []
9136
+ );
8956
9137
  const applyTargets = (0, import_react35.useCallback)((next) => {
8957
- for (const k of SECTION_KEYS) {
8958
- const v = next[k];
8959
- if (typeof v !== "number" || !Number.isFinite(v) || v < 0) {
8960
- next = { ...next, [k]: 0 };
8961
- }
9138
+ const sanitized = {
9139
+ top: _sanitize(next.top),
9140
+ mid: _sanitize(next.mid),
9141
+ bottom: _sanitize(next.bottom)
9142
+ };
9143
+ if (SECTION_KEYS.every((k) => appliedRef.current[k] === sanitized[k])) return;
9144
+ appliedRef.current = sanitized;
9145
+ layoutDebug("apply", { targets: sanitized });
9146
+ setLayoutHeights(sanitized);
9147
+ }, []);
9148
+ const clearProbe = (0, import_react35.useCallback)((k) => {
9149
+ const timer = probeTimers.current[k];
9150
+ if (timer) {
9151
+ clearInterval(timer);
9152
+ probeTimers.current[k] = null;
8962
9153
  }
8963
- if (stateRef.current.sections.bottom?.visible) {
8964
- const spec = stateRef.current.sections.bottom?.height;
8965
- const isCover = spec === "content" || spec === "minFillRest";
8966
- const natural = naturalsRef.current.bottom;
8967
- const floor = Math.max(next.bottom, H);
8968
- next = { ...next, bottom: isCover && natural <= bottomViewport() ? floor + BODY_TAIL : floor };
8969
- const fullBottom = !stateRef.current.sections.top?.visible && !stateRef.current.sections.mid?.visible;
8970
- if (fullBottom) {
8971
- next = {
8972
- ...next,
8973
- bottom: Math.max(0, next.bottom - (FULLBOTTOM_DIVISOR_H - FULLBOTTOM_OVERSCAN))
8974
- };
9154
+ }, []);
9155
+ const clearAllProbes = (0, import_react35.useCallback)(() => {
9156
+ SECTION_KEYS.forEach((k) => clearProbe(k));
9157
+ }, [clearProbe]);
9158
+ const recordMeasurement = (0, import_react35.useCallback)(
9159
+ (k, h, routeName) => {
9160
+ if (routeName !== currentRouteNameRef.current) return;
9161
+ if (!isValidMeasurement(h)) return;
9162
+ if (naturalsRef.current[k] === h) return;
9163
+ naturalsRef.current = { ...naturalsRef.current, [k]: h };
9164
+ writeNaturals(routeSnapshotRef.current, routeName, naturalsRef.current);
9165
+ layoutDebug("measure", {
9166
+ section: k,
9167
+ height: h,
9168
+ route: routeName,
9169
+ naturals: naturalsRef.current
9170
+ });
9171
+ applyTargets(computeTargets(stateRef.current));
9172
+ if (k === "bottom" && stateRef.current.pageScroll && stateRef.current.sections.bottom?.visible) {
9173
+ const overflows = bottomOverflows(stateRef.current, naturalsRef.current, HRef.current);
9174
+ setPageCanScroll(overflows);
9175
+ layoutDebug("pageScroll", { overflows });
9176
+ if (!overflows && bodyOverflowRef.current) {
9177
+ scrollRef.current?.scrollTo({ y: 0, animated: false });
9178
+ }
9179
+ bodyOverflowRef.current = overflows;
8975
9180
  }
8976
- }
8977
- setLayoutHeights((prev) => {
8978
- const changed = !SECTION_KEYS.every((k) => prev[k] === next[k]);
8979
- return changed ? next : prev;
8980
- });
8981
- }, [H]);
8982
- const makeOnMeasure = (k) => (e) => {
8983
- const h = e.nativeEvent.layout.height;
8984
- const prev = lastMeasured.current[k];
8985
- if (!Number.isFinite(h) || h <= 0) return;
8986
- const inRemountWindow = Date.now() - routeChangedAt.current < REMOUNT_WINDOW_MS;
8987
- const collapsed = inRemountWindow && prev > 0 && h < Math.max(prev * 0.5, 100);
8988
- if (collapsed) return;
8989
- naturalsRef.current[k] = h;
8990
- lastMeasured.current[k] = h;
8991
- if (k === "bottom" && state.pageScroll && stateRef.current.sections.bottom?.visible) {
8992
- const overflows = naturalsRef.current.bottom > bottomViewport();
8993
- setPageCanScroll(overflows);
8994
- if (!overflows && bodyOverflowRef.current) {
8995
- scrollRef.current?.scrollTo({ y: 0, animated: false });
9181
+ },
9182
+ [applyTargets, computeTargets]
9183
+ );
9184
+ const startProbe = (0, import_react35.useCallback)(
9185
+ (k) => {
9186
+ clearProbe(k);
9187
+ const routeAtStart = currentRouteNameRef.current;
9188
+ const startedAt = Date.now();
9189
+ probeLast.current[k] = null;
9190
+ probeStable.current[k] = 0;
9191
+ probeTimers.current[k] = setInterval(() => {
9192
+ const view = proxyRefs.current[k];
9193
+ if (!view || currentRouteNameRef.current !== routeAtStart) {
9194
+ clearProbe(k);
9195
+ return;
9196
+ }
9197
+ view.measure((_x, _y, _w, h) => {
9198
+ if (currentRouteNameRef.current !== routeAtStart) {
9199
+ clearProbe(k);
9200
+ return;
9201
+ }
9202
+ if (!isValidMeasurement(h)) return;
9203
+ const last = probeLast.current[k];
9204
+ probeLast.current[k] = h;
9205
+ if (last === h) {
9206
+ probeStable.current[k] = (probeStable.current[k] ?? 0) + 1;
9207
+ } else {
9208
+ probeStable.current[k] = 0;
9209
+ recordMeasurement(k, h, routeAtStart);
9210
+ }
9211
+ if ((probeStable.current[k] ?? 0) >= PROBE_STABLE_HITS || Date.now() - startedAt > PROBE_MAX_MS) {
9212
+ clearProbe(k);
9213
+ }
9214
+ });
9215
+ }, PROBE_INTERVAL_MS);
9216
+ },
9217
+ [clearProbe, recordMeasurement]
9218
+ );
9219
+ const onProxyLayout = (0, import_react35.useCallback)(
9220
+ (k) => (e) => {
9221
+ const h = e.nativeEvent.layout.height;
9222
+ if (isValidMeasurement(h)) {
9223
+ recordMeasurement(k, h, currentRouteNameRef.current);
8996
9224
  }
8997
- bodyOverflowRef.current = overflows;
8998
- }
8999
- const targets = computeTargets(state);
9000
- applyTargets(
9001
- animateTransitions && prevRoute !== null && !reduceMotion && inRemountWindow ? _withBottomHold(targets, layoutHeightsRef.current) : targets
9002
- );
9003
- };
9225
+ startProbe(k);
9226
+ },
9227
+ [recordMeasurement, startProbe]
9228
+ );
9004
9229
  (0, import_react35.useLayoutEffect)(() => {
9005
- if (!state.pageScroll) {
9230
+ const reset = shouldResetScroll(currentRouteNameRef.current, currentRoute.name);
9231
+ if (reset) {
9006
9232
  scrollRef.current?.scrollTo({ y: 0, animated: false });
9007
9233
  innerScrollRef.current?.scrollTo({ y: 0, animated: false });
9008
9234
  }
9009
- setPageCanScroll(
9010
- !!state.pageScroll && naturalsRef.current.bottom > bottomViewport()
9235
+ currentRouteNameRef.current = currentRoute.name;
9236
+ clearAllProbes();
9237
+ naturalsRef.current = seedNaturals(
9238
+ routeSnapshotRef.current,
9239
+ currentRoute.name,
9240
+ initialNaturals(HRef.current)
9011
9241
  );
9012
- routeChangedAt.current = Date.now();
9242
+ layoutDebug("seed", {
9243
+ route: currentRoute.name,
9244
+ lastRoute: prevRoute?.name ?? null,
9245
+ resetScroll: reset,
9246
+ naturals: naturalsRef.current
9247
+ });
9248
+ bodyOverflowRef.current = false;
9013
9249
  const targets = computeTargets(state);
9014
- const animated = animateTransitions && prevRoute !== null && !reduceMotion;
9015
- const applied = animated ? _withBottomHold(targets, layoutHeightsRef.current) : targets;
9016
- if (settleTimer.current) {
9017
- clearTimeout(settleTimer.current);
9018
- settleTimer.current = null;
9019
- }
9020
- if (applied !== targets) {
9021
- settleTimer.current = setTimeout(() => {
9022
- settleTimer.current = null;
9023
- applyTargets(targets);
9024
- }, LAYOUT_DURATION);
9025
- }
9026
- applyTargets(applied);
9250
+ applyTargets(targets);
9251
+ const overflows = !!state.pageScroll && bottomOverflows(state, naturalsRef.current, HRef.current);
9252
+ setPageCanScroll(overflows);
9253
+ layoutDebug("route", {
9254
+ route: currentRoute.name,
9255
+ state: currentRoute.state,
9256
+ targets,
9257
+ pageCanScroll: overflows
9258
+ });
9027
9259
  if (revealEnabled && prevRoute) {
9028
9260
  startReveal();
9029
9261
  }
@@ -9033,51 +9265,25 @@ function AppLayout({
9033
9265
  const cur = state.sections[k];
9034
9266
  const prevB = prevLayoutState?.sections[k];
9035
9267
  const prevVisible = !!prevB?.visible;
9036
- const visible = !!cur?.visible || prevVisible;
9037
- const isDynamic = ["content", "minFillRest"].includes(
9038
- cur?.height ?? prevB?.height
9039
- );
9040
- const target = computeTargets(state);
9041
- const height = isDynamic ? Math.max(layoutHeights[k], target[k]) : layoutHeights[k];
9042
- let inner;
9043
- if (!visible) {
9044
- inner = /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.measureCopy, onLayout: makeOnMeasure(k), children: cur?.slot ? slots[cur.slot] : null });
9045
- } else {
9046
- const usePrevContent = !cur?.visible && prevVisible;
9047
- const slot = usePrevContent ? prevB?.slot : cur?.slot;
9048
- const content = slot ? usePrevContent ? prevRoute?.slots?.[slot] : slots[slot] : null;
9049
- const scroll = cur?.scroll ?? prevB?.scroll ?? false;
9050
- const selfMeasured = isDynamic && !scroll;
9051
- const body = scroll ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9052
- import_react_native77.ScrollView,
9053
- {
9054
- ref: innerScrollRef,
9055
- style: styles71.innerScroll,
9056
- showsVerticalScrollIndicator: false,
9057
- children: content
9058
- }
9059
- ) : selfMeasured ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.measureNatural, onLayout: makeOnMeasure(k), children: content }) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.sectionContent, children: content });
9060
- const revealContent = revealEnabled;
9061
- inner = /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
9062
- isDynamic && !selfMeasured && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9063
- import_react_native77.View,
9064
- {
9065
- pointerEvents: "none",
9066
- style: styles71.measureOuter,
9067
- onLayout: makeOnMeasure(k),
9068
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.measureCopy, children: content })
9069
- }
9070
- ),
9071
- revealContent ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9072
- import_react_native77.View,
9073
- {
9074
- style: [styles71.reveal, revealHidden && styles71.revealHidden],
9075
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native_reanimated16.default.View, { style: [styles71.reveal, revealStyle], children: body })
9076
- }
9077
- ) : body
9078
- ] });
9079
- }
9080
- const bg = cur?.backgroundColor ?? prevB?.backgroundColor ?? DEFAULT_COLORS[k];
9268
+ if (!cur?.visible && !prevVisible) return null;
9269
+ const usePrevContent = !cur?.visible && prevVisible;
9270
+ const behavior = usePrevContent ? prevB : cur;
9271
+ const slot = behavior?.slot;
9272
+ const content = slot ? usePrevContent ? prevRoute?.slots?.[slot] : slots[slot] : null;
9273
+ const isDynamic = behavior?.height === "content" || behavior?.height === "minFillRest";
9274
+ const scroll = behavior?.scroll ?? false;
9275
+ const height = layoutHeights[k];
9276
+ const bg = behavior?.backgroundColor ?? SECTION_DEFAULT_COLORS[k];
9277
+ const measureCurrent = isDynamic && !usePrevContent;
9278
+ const body = scroll ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9279
+ import_react_native77.ScrollView,
9280
+ {
9281
+ ref: innerScrollRef,
9282
+ style: styles71.innerScroll,
9283
+ showsVerticalScrollIndicator: false,
9284
+ children: content
9285
+ }
9286
+ ) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.sectionContent, children: content });
9081
9287
  return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
9082
9288
  import_react_native_reanimated16.default.View,
9083
9289
  {
@@ -9085,90 +9291,71 @@ function AppLayout({
9085
9291
  collapsable: false,
9086
9292
  style: [
9087
9293
  styles71.colBlock,
9088
- { backgroundColor: bg, height },
9089
- hasTransition && animateTransitions && styles71.clip
9294
+ { backgroundColor: bg, height }
9090
9295
  ],
9091
9296
  children: [
9092
- k === "bottom" && showFullBottomDivisor && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9297
+ measureCurrent && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9093
9298
  import_react_native77.View,
9094
9299
  {
9300
+ ref: (r) => {
9301
+ proxyRefs.current[k] = r;
9302
+ },
9095
9303
  pointerEvents: "none",
9096
- style: {
9097
- position: "absolute",
9098
- left: 0,
9099
- right: 0,
9100
- bottom: -FULLBOTTOM_CUSHION,
9101
- height: FULLBOTTOM_CUSHION,
9102
- backgroundColor: bg
9103
- }
9304
+ style: styles71.measureOuter,
9305
+ onLayout: onProxyLayout(k),
9306
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.measureCopy, children: content })
9104
9307
  }
9105
9308
  ),
9106
- inner
9309
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: [styles71.sectionFill, hasTransition && animateTransitions && styles71.clip], children: revealEnabled ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: [styles71.reveal, revealHidden && styles71.revealHidden], children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native_reanimated16.default.View, { style: [styles71.reveal, revealStyle], children: body }) }) : body })
9107
9310
  ]
9108
9311
  },
9109
9312
  k
9110
9313
  );
9111
9314
  };
9112
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(AppNavigationContext.Provider, { value: navigationValue, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
9113
- import_react_native77.View,
9114
- {
9115
- ref: rootViewRef,
9116
- style: [styles71.root, { backgroundColor: pageBg }],
9117
- children: [
9118
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
9119
- import_react_native77.ScrollView,
9120
- {
9121
- ref: scrollRef,
9122
- style: styles71.pageScroll,
9123
- contentContainerStyle: [styles71.pageContent, { backgroundColor: pageBg }],
9124
- scrollEnabled: !!state.pageScroll && pageCanScroll,
9125
- bounces: false,
9126
- overScrollMode: "never",
9127
- showsVerticalScrollIndicator: false,
9128
- children: [
9129
- renderSection("top"),
9130
- showTopDivisor && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9131
- import_react_native_reanimated16.default.View,
9132
- {
9133
- layout: hasTransition && animateTransitions ? transition2 : void 0,
9134
- collapsable: false,
9135
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Divisor, { position: "top", handle: currentRoute.state === "top" })
9136
- }
9137
- ),
9138
- renderSection("mid"),
9139
- (showBottomDivisor || showFullBottomDivisor) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9140
- import_react_native_reanimated16.default.View,
9315
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(AppNavigationContext.Provider, { value: navigationValue, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_react_native77.View, { style: [styles71.root, { backgroundColor: pageBg }], children: [
9316
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
9317
+ import_react_native77.ScrollView,
9318
+ {
9319
+ ref: scrollRef,
9320
+ style: styles71.pageScroll,
9321
+ contentContainerStyle: [styles71.pageContent, { backgroundColor: pageBg }],
9322
+ scrollEnabled: !!state.pageScroll && pageCanScroll,
9323
+ bounces: false,
9324
+ overScrollMode: "never",
9325
+ showsVerticalScrollIndicator: false,
9326
+ children: [
9327
+ renderSection("top"),
9328
+ showTopDivisor && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9329
+ import_react_native_reanimated16.default.View,
9330
+ {
9331
+ layout: hasTransition && animateTransitions ? transition2 : void 0,
9332
+ collapsable: false,
9333
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Divisor, { position: "top", handle: currentRoute.state === "top" })
9334
+ }
9335
+ ),
9336
+ renderSection("mid"),
9337
+ (showBottomDivisor || showFullBottomDivisor) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9338
+ import_react_native_reanimated16.default.View,
9339
+ {
9340
+ layout: hasTransition && animateTransitions ? transition2 : void 0,
9341
+ collapsable: false,
9342
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9343
+ Divisor,
9141
9344
  {
9142
- layout: hasTransition && animateTransitions ? transition2 : void 0,
9143
- collapsable: false,
9144
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { ref: capHolderRef, collapsable: false, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
9145
- Divisor,
9146
- {
9147
- position: "bottom",
9148
- handle: currentRoute.state === "bottom" || showFullBottomDivisor,
9149
- height: FULLBOTTOM_DIVISOR_H,
9150
- extend: showFullBottomDivisor ? FULLBOTTOM_EXTEND : 0,
9151
- style: (
9152
- // El traslado de 5px es para ubicar el borde bajo el mid
9153
- // (header). En full-bottom no hay header: el cap sobresale
9154
- // FULLBOTTOM_OVERSCAN px por encima del tope (recortado por
9155
- // el ScrollView) y FULLBOTTOM_EXTEND px sobre la hoja; la
9156
- // hoja se contrae en (FULLBOTTOM_DIVISOR_H - OVERSCAN) para
9157
- // que divisor + hoja sigan sumando exactamente una pantalla.
9158
- showFullBottomDivisor ? { marginTop: -FULLBOTTOM_OVERSCAN } : { transform: [{ translateY: 5 }] }
9159
- )
9160
- }
9161
- ) })
9345
+ position: "bottom",
9346
+ handle: currentRoute.state === "bottom" || showFullBottomDivisor,
9347
+ height: FULLBOTTOM_DIVISOR_H,
9348
+ style: showFullBottomDivisor ? void 0 : { transform: [{ translateY: 5 }] }
9162
9349
  }
9163
- ),
9164
- renderSection("bottom")
9165
- ]
9166
- }
9167
- ),
9168
- showBackButton && canGoBack && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.backBar, pointerEvents: "box-none", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Button, { variant: "secondary", size: "sm", label: "\u2190 Volver", onPress: back }) })
9169
- ]
9170
- }
9171
- ) });
9350
+ )
9351
+ }
9352
+ ),
9353
+ renderSection("bottom")
9354
+ ]
9355
+ }
9356
+ ),
9357
+ showBackButton && canGoBack && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_react_native77.View, { style: styles71.backBar, pointerEvents: "box-none", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Button, { variant: "secondary", size: "sm", label: "\u2190 Volver", onPress: back }) })
9358
+ ] }) });
9172
9359
  }
9173
9360
  var styles71 = import_react_native77.StyleSheet.create({
9174
9361
  root: {
@@ -9184,6 +9371,11 @@ var styles71 = import_react_native77.StyleSheet.create({
9184
9371
  width: "100%",
9185
9372
  position: "relative"
9186
9373
  },
9374
+ // El contenido visible llena la sección de alto fijo. El recorte de la
9375
+ // transición se agrega encima (styles.clip) solo cuando hay morph.
9376
+ sectionFill: {
9377
+ flex: 1
9378
+ },
9187
9379
  clip: {
9188
9380
  overflow: "hidden"
9189
9381
  },
@@ -9193,6 +9385,8 @@ var styles71 = import_react_native77.StyleSheet.create({
9193
9385
  revealHidden: {
9194
9386
  opacity: 0
9195
9387
  },
9388
+ // Proxy de medición: absoluto, invisible y sin alto fijo. Mide la altura
9389
+ // intrínseca real del contenido sin que el alto de la sección lo restrinja.
9196
9390
  measureOuter: {
9197
9391
  position: "absolute",
9198
9392
  top: 0,
@@ -9204,9 +9398,6 @@ var styles71 = import_react_native77.StyleSheet.create({
9204
9398
  measureCopy: {
9205
9399
  width: "100%"
9206
9400
  },
9207
- measureNatural: {
9208
- width: "100%"
9209
- },
9210
9401
  sectionContent: {
9211
9402
  flex: 1
9212
9403
  },
@@ -9223,7 +9414,7 @@ var styles71 = import_react_native77.StyleSheet.create({
9223
9414
 
9224
9415
  // src/layout/AppShell.tsx
9225
9416
  var import_react36 = require("react");
9226
- var import_react_native79 = require("react-native");
9417
+ var import_react_native78 = require("react-native");
9227
9418
  var import_jsx_runtime79 = require("react/jsx-runtime");
9228
9419
  var AppShellContext = (0, import_react36.createContext)(null);
9229
9420
  function useAppShell() {
@@ -9275,7 +9466,7 @@ function AppShell({
9275
9466
  setStack([name]);
9276
9467
  }, []);
9277
9468
  (0, import_react36.useEffect)(() => {
9278
- const sub = import_react_native79.BackHandler.addEventListener("hardwareBackPress", () => {
9469
+ const sub = import_react_native78.BackHandler.addEventListener("hardwareBackPress", () => {
9279
9470
  if (stack.length > 1) {
9280
9471
  back();
9281
9472
  return true;
@@ -9321,7 +9512,7 @@ function directionSign(dir) {
9321
9512
  }
9322
9513
 
9323
9514
  // src/components/camera/CameraScreenContainer.tsx
9324
- var import_react_native80 = require("react-native");
9515
+ var import_react_native79 = require("react-native");
9325
9516
 
9326
9517
  // src/components/camera/palette.ts
9327
9518
  var import_antonella_theme72 = require("@william-callao/antonella-theme");
@@ -9345,9 +9536,9 @@ var cameraPalette = {
9345
9536
  // src/components/camera/CameraScreenContainer.tsx
9346
9537
  var import_jsx_runtime80 = require("react/jsx-runtime");
9347
9538
  function CameraScreenContainer({ children, style }) {
9348
- return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_react_native80.View, { accessibilityViewIsModal: true, style: [styles72.root, style], testID: "camera-screen-container", children });
9539
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_react_native79.View, { accessibilityViewIsModal: true, style: [styles72.root, style], testID: "camera-screen-container", children });
9349
9540
  }
9350
- var styles72 = import_react_native80.StyleSheet.create({
9541
+ var styles72 = import_react_native79.StyleSheet.create({
9351
9542
  root: {
9352
9543
  flex: 1,
9353
9544
  backgroundColor: cameraPalette.background,
@@ -9358,12 +9549,12 @@ var styles72 = import_react_native80.StyleSheet.create({
9358
9549
  // src/components/camera/CameraPermissionGate.tsx
9359
9550
  var import_react37 = __toESM(require("react"));
9360
9551
  var import_expo_camera = require("expo-camera");
9361
- var import_react_native82 = require("react-native");
9552
+ var import_react_native81 = require("react-native");
9362
9553
  var import_react_native_safe_area_context10 = require("react-native-safe-area-context");
9363
9554
  var import_antonella_theme74 = require("@william-callao/antonella-theme");
9364
9555
 
9365
9556
  // src/components/camera/CameraHud.tsx
9366
- var import_react_native81 = require("react-native");
9557
+ var import_react_native80 = require("react-native");
9367
9558
  var import_react_native_safe_area_context9 = require("react-native-safe-area-context");
9368
9559
  var import_antonella_theme73 = require("@william-callao/antonella-theme");
9369
9560
  var import_jsx_runtime81 = require("react/jsx-runtime");
@@ -9383,16 +9574,16 @@ function CameraHud({
9383
9574
  }) {
9384
9575
  const insets = (0, import_react_native_safe_area_context9.useSafeAreaInsets)();
9385
9576
  const isCapture = onCapture != null;
9386
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_react_native81.View, { style: import_react_native81.StyleSheet.absoluteFill, pointerEvents: "box-none", children: [
9577
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_react_native80.View, { style: import_react_native80.StyleSheet.absoluteFill, pointerEvents: "box-none", children: [
9387
9578
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
9388
- import_react_native81.View,
9579
+ import_react_native80.View,
9389
9580
  {
9390
9581
  style: [styles73.topBar, { paddingTop: insets.top + import_antonella_theme73.space.space2 }],
9391
9582
  pointerEvents: "box-none",
9392
9583
  children: [
9393
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(HudIconButton, { icon: closeIcon, label: "Volver", onPress: onClose }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.topSlot }),
9394
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.topTitle, children: title ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Text, { variant: "label", color: cameraPalette.text, children: title }) : null }),
9395
- isCapture ? flash != null && onToggleFlash ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(FlashButton, { flash, onPress: onToggleFlash }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.topSlot }) : torch != null && onToggleTorch ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
9584
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(HudIconButton, { icon: closeIcon, label: "Volver", onPress: onClose }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.topSlot }),
9585
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.topTitle, children: title ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(Text, { variant: "label", color: cameraPalette.text, children: title }) : null }),
9586
+ isCapture ? flash != null && onToggleFlash ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(FlashButton, { flash, onPress: onToggleFlash }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.topSlot }) : torch != null && onToggleTorch ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
9396
9587
  HudIconButton,
9397
9588
  {
9398
9589
  icon: torch ? "torch" : "torch-off",
@@ -9400,19 +9591,19 @@ function CameraHud({
9400
9591
  active: torch,
9401
9592
  onPress: onToggleTorch
9402
9593
  }
9403
- ) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.topSlot })
9594
+ ) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.topSlot })
9404
9595
  ]
9405
9596
  }
9406
9597
  ),
9407
9598
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
9408
- import_react_native81.View,
9599
+ import_react_native80.View,
9409
9600
  {
9410
9601
  style: [styles73.bottomBar, { paddingBottom: Math.max(insets.bottom, import_antonella_theme73.space.space4) }],
9411
9602
  pointerEvents: "box-none",
9412
9603
  children: [
9413
- onFlipCamera && canFlipCamera ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(HudIconButton, { icon: "flip-camera", label: "Girar c\xE1mara", onPress: onFlipCamera }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.bottomSlot }),
9414
- isCapture && onCapture ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ShutterButton, { busy: capturing, enabled: canCapture, onPress: onCapture }) : torch != null && onToggleTorch ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(BigTorchButton, { torch, onPress: onToggleTorch }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.bottomSlot }),
9415
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.bottomSlot })
9604
+ onFlipCamera && canFlipCamera ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(HudIconButton, { icon: "flip-camera", label: "Girar c\xE1mara", onPress: onFlipCamera }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.bottomSlot }),
9605
+ isCapture && onCapture ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ShutterButton, { busy: capturing, enabled: canCapture, onPress: onCapture }) : torch != null && onToggleTorch ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(BigTorchButton, { torch, onPress: onToggleTorch }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.bottomSlot }),
9606
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.bottomSlot })
9416
9607
  ]
9417
9608
  }
9418
9609
  )
@@ -9420,7 +9611,7 @@ function CameraHud({
9420
9611
  }
9421
9612
  function HudIconButton({ icon, label, onPress, active = false, size = "md" }) {
9422
9613
  return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
9423
- import_react_native81.Pressable,
9614
+ import_react_native80.Pressable,
9424
9615
  {
9425
9616
  accessibilityRole: "button",
9426
9617
  accessibilityLabel: label,
@@ -9449,7 +9640,7 @@ function FlashButton({ flash, onPress }) {
9449
9640
  const active = flash !== "off";
9450
9641
  const label = flash === "auto" ? "Auto" : active ? "Flash" : "Apagado";
9451
9642
  return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
9452
- import_react_native81.Pressable,
9643
+ import_react_native80.Pressable,
9453
9644
  {
9454
9645
  accessibilityRole: "button",
9455
9646
  accessibilityLabel: `Flash: ${label}`,
@@ -9483,7 +9674,7 @@ function ShutterButton({
9483
9674
  }) {
9484
9675
  const disabledShutter = busy || enabled === false || onPress == null;
9485
9676
  return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
9486
- import_react_native81.Pressable,
9677
+ import_react_native80.Pressable,
9487
9678
  {
9488
9679
  accessibilityRole: "button",
9489
9680
  accessibilityLabel: "Tomar foto",
@@ -9495,11 +9686,11 @@ function ShutterButton({
9495
9686
  pressed && !disabledShutter && styles73.shutterPressed,
9496
9687
  disabledShutter && styles73.shutterDisabled
9497
9688
  ],
9498
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.View, { style: styles73.shutterInner, children: busy ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native81.ActivityIndicator, { color: cameraPalette.background }) : null })
9689
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.View, { style: styles73.shutterInner, children: busy ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_react_native80.ActivityIndicator, { color: cameraPalette.background }) : null })
9499
9690
  }
9500
9691
  );
9501
9692
  }
9502
- var styles73 = import_react_native81.StyleSheet.create({
9693
+ var styles73 = import_react_native80.StyleSheet.create({
9503
9694
  topBar: {
9504
9695
  position: "absolute",
9505
9696
  top: 0,
@@ -9618,12 +9809,12 @@ function CameraStatus({
9618
9809
  }) {
9619
9810
  const insets = (0, import_react_native_safe_area_context10.useSafeAreaInsets)();
9620
9811
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(CameraScreenContainer, { children: [
9621
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_react_native82.View, { style: [styles74.header, { paddingTop: insets.top + import_antonella_theme74.space.space2 }], children: [
9622
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(HudIconButton, { icon: "arrow-back", label: "Volver", onPress: onClose }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react_native82.View, { style: styles74.headerSlot }),
9623
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react_native82.View, { style: styles74.headerTitle, children: title ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Text, { variant: "label", color: cameraPalette.text, children: title }) : null }),
9624
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react_native82.View, { style: styles74.headerSlot })
9812
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_react_native81.View, { style: [styles74.header, { paddingTop: insets.top + import_antonella_theme74.space.space2 }], children: [
9813
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(HudIconButton, { icon: "arrow-back", label: "Volver", onPress: onClose }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react_native81.View, { style: styles74.headerSlot }),
9814
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react_native81.View, { style: styles74.headerTitle, children: title ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(Text, { variant: "label", color: cameraPalette.text, children: title }) : null }),
9815
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_react_native81.View, { style: styles74.headerSlot })
9625
9816
  ] }),
9626
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_react_native82.View, { style: styles74.body, children: [
9817
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_react_native81.View, { style: styles74.body, children: [
9627
9818
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9628
9819
  Icon,
9629
9820
  {
@@ -9638,7 +9829,7 @@ function CameraStatus({
9638
9829
  ] })
9639
9830
  ] });
9640
9831
  }
9641
- var styles74 = import_react_native82.StyleSheet.create({
9832
+ var styles74 = import_react_native81.StyleSheet.create({
9642
9833
  header: {
9643
9834
  paddingHorizontal: import_antonella_theme74.space.space4,
9644
9835
  paddingBottom: import_antonella_theme74.space.space3,
@@ -9678,7 +9869,7 @@ var styles74 = import_react_native82.StyleSheet.create({
9678
9869
  // src/components/camera/CameraCaptureScreen.tsx
9679
9870
  var import_react38 = require("react");
9680
9871
  var import_expo_camera2 = require("expo-camera");
9681
- var import_react_native83 = require("react-native");
9872
+ var import_react_native82 = require("react-native");
9682
9873
  var import_jsx_runtime83 = require("react/jsx-runtime");
9683
9874
  var FLASH_ORDER = ["off", "on", "auto"];
9684
9875
  function CameraCaptureScreen({
@@ -9739,7 +9930,7 @@ function CameraCaptureScreen({
9739
9930
  import_expo_camera2.CameraView,
9740
9931
  {
9741
9932
  ref: cameraRef,
9742
- style: import_react_native83.StyleSheet.absoluteFill,
9933
+ style: import_react_native82.StyleSheet.absoluteFill,
9743
9934
  facing: facingState,
9744
9935
  flash: flashState,
9745
9936
  mirror: facingState === "front" ? mirrorFront : void 0,
@@ -9772,7 +9963,7 @@ function CameraCaptureScreen({
9772
9963
  // src/components/camera/BarcodeScannerScreen.tsx
9773
9964
  var import_react39 = require("react");
9774
9965
  var import_expo_camera3 = require("expo-camera");
9775
- var import_react_native84 = require("react-native");
9966
+ var import_react_native83 = require("react-native");
9776
9967
  var import_react_native_reanimated17 = __toESM(require("react-native-reanimated"));
9777
9968
  var import_antonella_theme75 = require("@william-callao/antonella-theme");
9778
9969
  var import_jsx_runtime84 = require("react/jsx-runtime");
@@ -9807,7 +9998,7 @@ function BarcodeScannerScreen({
9807
9998
  if (now - lastScanAt.current < throttleMs) return;
9808
9999
  lastScanAt.current = now;
9809
10000
  locked.current = true;
9810
- if (haptics && import_react_native84.Platform.OS !== "web") import_react_native84.Vibration.vibrate(80);
10001
+ if (haptics && import_react_native83.Platform.OS !== "web") import_react_native83.Vibration.vibrate(80);
9811
10002
  onScan?.({ type: result.type, value: result.data });
9812
10003
  setTimeout(() => {
9813
10004
  locked.current = false;
@@ -9825,7 +10016,7 @@ function BarcodeScannerScreen({
9825
10016
  /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
9826
10017
  import_expo_camera3.CameraView,
9827
10018
  {
9828
- style: import_react_native84.StyleSheet.absoluteFill,
10019
+ style: import_react_native83.StyleSheet.absoluteFill,
9829
10020
  facing: facingState,
9830
10021
  enableTorch: torch,
9831
10022
  mode: "picture",
@@ -9870,17 +10061,17 @@ function Viewfinder({ caption }) {
9870
10061
  const lineStyle = (0, import_react_native_reanimated17.useAnimatedStyle)(() => ({
9871
10062
  transform: [{ translateY: box ? progress.value * Math.max(0, box.h - 24) : 0 }]
9872
10063
  }));
9873
- return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: import_react_native84.StyleSheet.absoluteFill, pointerEvents: "none", onLayout, children: box ? /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
9874
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: [styles75.dim, styles75.dimTop, { height: box.y }] }),
10064
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: import_react_native83.StyleSheet.absoluteFill, pointerEvents: "none", onLayout, children: box ? /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
10065
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: [styles75.dim, styles75.dimTop, { height: box.y }] }),
9875
10066
  /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
9876
- import_react_native84.View,
10067
+ import_react_native83.View,
9877
10068
  {
9878
10069
  style: [styles75.dim, styles75.dimBottom, { top: box.y + box.h }]
9879
10070
  }
9880
10071
  ),
9881
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: [styles75.dim, styles75.dimSide, { top: box.y, height: box.h, left: 0, width: box.x }] }),
10072
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: [styles75.dim, styles75.dimSide, { top: box.y, height: box.h, left: 0, width: box.x }] }),
9882
10073
  /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
9883
- import_react_native84.View,
10074
+ import_react_native83.View,
9884
10075
  {
9885
10076
  style: [
9886
10077
  styles75.dim,
@@ -9890,7 +10081,7 @@ function Viewfinder({ caption }) {
9890
10081
  }
9891
10082
  ),
9892
10083
  /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
9893
- import_react_native84.View,
10084
+ import_react_native83.View,
9894
10085
  {
9895
10086
  style: [
9896
10087
  styles75.box,
@@ -9898,12 +10089,12 @@ function Viewfinder({ caption }) {
9898
10089
  ]
9899
10090
  }
9900
10091
  ),
9901
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: [styles75.corner, styles75.cornerTL, { left: box.x - 2, top: box.y - 2 }] }),
9902
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: [styles75.corner, styles75.cornerTR, { right: void 0, left: box.x + box.w - 22, top: box.y - 2 }] }),
9903
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: [styles75.corner, styles75.cornerBL, { left: box.x - 2, top: box.y + box.h - 22 }] }),
9904
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native84.View, { style: [styles75.corner, styles75.cornerBR, { left: box.x + box.w - 22, top: box.y + box.h - 22 }] }),
10092
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: [styles75.corner, styles75.cornerTL, { left: box.x - 2, top: box.y - 2 }] }),
10093
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: [styles75.corner, styles75.cornerTR, { right: void 0, left: box.x + box.w - 22, top: box.y - 2 }] }),
10094
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: [styles75.corner, styles75.cornerBL, { left: box.x - 2, top: box.y + box.h - 22 }] }),
10095
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_react_native83.View, { style: [styles75.corner, styles75.cornerBR, { left: box.x + box.w - 22, top: box.y + box.h - 22 }] }),
9905
10096
  /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
9906
- import_react_native84.View,
10097
+ import_react_native83.View,
9907
10098
  {
9908
10099
  style: [
9909
10100
  styles75.scanArea,
@@ -9923,7 +10114,7 @@ function Viewfinder({ caption }) {
9923
10114
  ) : null
9924
10115
  ] }) : null });
9925
10116
  }
9926
- var styles75 = import_react_native84.StyleSheet.create({
10117
+ var styles75 = import_react_native83.StyleSheet.create({
9927
10118
  dim: {
9928
10119
  position: "absolute",
9929
10120
  backgroundColor: cameraPalette.overlay
@@ -10118,10 +10309,13 @@ var import_antonella_theme76 = require("@william-callao/antonella-theme");
10118
10309
  hasCode,
10119
10310
  hostDirection,
10120
10311
  iconMap,
10312
+ isLayoutDebug,
10313
+ layoutDebug,
10121
10314
  layoutStates,
10122
10315
  removeNode,
10123
10316
  resolveComposition,
10124
10317
  resolveTransition,
10318
+ setLayoutDebug,
10125
10319
  updateNode,
10126
10320
  useAppNavigation,
10127
10321
  useAppShell,