silvery 0.21.1 → 0.23.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 (171) hide show
  1. package/dist/{Text-BRf-59j2.mjs → Text-Ci6UCSTL.mjs} +46 -46
  2. package/dist/Text-Ci6UCSTL.mjs.map +1 -0
  3. package/dist/{ag-BeFC4S2N.mjs → ag-q9lRlKlt.mjs} +42 -19
  4. package/dist/ag-q9lRlKlt.mjs.map +1 -0
  5. package/dist/{animation-N8MFybTk.mjs → animation-CZ4x2R7C.mjs} +1 -1
  6. package/dist/{animation-N8MFybTk.mjs.map → animation-CZ4x2R7C.mjs.map} +1 -1
  7. package/dist/{ansi-C6Qs1Wn2.mjs → ansi-CLmIMnop.mjs} +1 -1
  8. package/dist/{ansi-C6Qs1Wn2.mjs.map → ansi-CLmIMnop.mjs.map} +1 -1
  9. package/dist/{ansi-CBkam1ty.d.mts → ansi-zmNzgkPB.d.mts} +1 -1
  10. package/dist/{ansi-CBkam1ty.d.mts.map → ansi-zmNzgkPB.d.mts.map} +1 -1
  11. package/dist/backend-DSiSIc-h.mjs +13396 -0
  12. package/dist/backend-DSiSIc-h.mjs.map +1 -0
  13. package/dist/chain-bridge-CkYcMxlq.mjs +4149 -0
  14. package/dist/chain-bridge-CkYcMxlq.mjs.map +1 -0
  15. package/dist/{chunk-hT5z_Zn9.mjs → chunk-BEJ448es.mjs} +1 -1
  16. package/dist/cli-VNqUKlXw.mjs +4 -0
  17. package/dist/{context-BU5LkkIy.mjs → context-CEhuD1R_.mjs} +1 -1
  18. package/dist/{context-BU5LkkIy.mjs.map → context-CEhuD1R_.mjs.map} +1 -1
  19. package/dist/devtools-BF4IMumr.mjs +2 -0
  20. package/dist/{devtools-9zfhpFyG.mjs → devtools-td2AjFwc.mjs} +5 -4
  21. package/dist/{devtools-9zfhpFyG.mjs.map → devtools-td2AjFwc.mjs.map} +1 -1
  22. package/dist/{easing-B0oZKDki.d.mts → easing-C5MrdO7V.d.mts} +1 -1
  23. package/dist/{easing-B0oZKDki.d.mts.map → easing-C5MrdO7V.d.mts.map} +1 -1
  24. package/dist/{eta-DGOuC8yU.mjs → eta-BwYWEjfS.mjs} +1 -5
  25. package/dist/{eta-DGOuC8yU.mjs.map → eta-BwYWEjfS.mjs.map} +1 -1
  26. package/dist/{flexily-zero-adapter-D6hcFgrH.mjs → flexily-zero-adapter-DktX3HsX.mjs} +1 -1
  27. package/dist/{flexily-zero-adapter-CEJOcbNp.mjs → flexily-zero-adapter-VoBGHG14.mjs} +1 -1
  28. package/dist/{flexily-zero-adapter-CEJOcbNp.mjs.map → flexily-zero-adapter-VoBGHG14.mjs.map} +1 -1
  29. package/dist/hit-registry-D_nxOivS.d.mts +71 -0
  30. package/dist/hit-registry-D_nxOivS.d.mts.map +1 -0
  31. package/dist/{image-1nRyKa60.mjs → image-CIF75xMr.mjs} +24 -24
  32. package/dist/image-CIF75xMr.mjs.map +1 -0
  33. package/dist/{index-2E1jYgak.d.mts → index-377zdPLP.d.mts} +35 -12
  34. package/dist/index-377zdPLP.d.mts.map +1 -0
  35. package/dist/{index-DnuadDNL.d.mts → index-BcSr0RAQ.d.mts} +8590 -11173
  36. package/dist/index-BcSr0RAQ.d.mts.map +1 -0
  37. package/dist/{index-Dg1YaeJb.d.mts → index-DLnpxDAm.d.mts} +2 -2
  38. package/dist/{index-Dg1YaeJb.d.mts.map → index-DLnpxDAm.d.mts.map} +1 -1
  39. package/dist/{index-Bi4Jdz5g.d.mts → index-DlNmckTq.d.mts} +2 -2
  40. package/dist/{index-Bi4Jdz5g.d.mts.map → index-DlNmckTq.d.mts.map} +1 -1
  41. package/dist/index.d.mts +12 -8
  42. package/dist/index.d.mts.map +1 -1
  43. package/dist/index.mjs +18 -17
  44. package/dist/index.mjs.map +1 -1
  45. package/dist/{layout-engine-Ca_nbtfL.mjs → layout-engine-BgR58vL0.mjs} +3 -3
  46. package/dist/{layout-engine-Ca_nbtfL.mjs.map → layout-engine-BgR58vL0.mjs.map} +1 -1
  47. package/dist/{layout-engine-CgsoBRIn.mjs → layout-engine-DNjTha8f.mjs} +1 -1
  48. package/dist/{layout-signals-Dch2EiCy.mjs → layout-signals-CGYbHmxy.mjs} +2 -2
  49. package/dist/layout-signals-CGYbHmxy.mjs.map +1 -0
  50. package/dist/{bound-term-BumfuXXW.d.mts → mouse-events-B2z5tbsL.d.mts} +540 -401
  51. package/dist/mouse-events-B2z5tbsL.d.mts.map +1 -0
  52. package/dist/{mouse-events-hnbJZRwK.mjs → mouse-events-WQ2h-uqG.mjs} +14 -6
  53. package/dist/mouse-events-WQ2h-uqG.mjs.map +1 -0
  54. package/dist/{multi-progress-Bg4ngK80.d.mts → multi-progress-BaEFfHKP.d.mts} +2 -2
  55. package/dist/{multi-progress-Bg4ngK80.d.mts.map → multi-progress-BaEFfHKP.d.mts.map} +1 -1
  56. package/dist/{multi-progress-CaXTuL9G.mjs → multi-progress-zCWHEm9P.mjs} +3 -3
  57. package/dist/{multi-progress-CaXTuL9G.mjs.map → multi-progress-zCWHEm9P.mjs.map} +1 -1
  58. package/dist/{node-BiFu8I9Y.mjs → node-CJ3J_rW-.mjs} +4 -4
  59. package/dist/node-CJ3J_rW-.mjs.map +1 -0
  60. package/dist/{progress-B_UPy6zk.mjs → progress-6vJ7nxUg.mjs} +4 -4
  61. package/dist/{progress-B_UPy6zk.mjs.map → progress-6vJ7nxUg.mjs.map} +1 -1
  62. package/dist/{progress-bar-DmIMPdL0.mjs → progress-bar-BlFNsZL8.mjs} +4 -4
  63. package/dist/{progress-bar-DmIMPdL0.mjs.map → progress-bar-BlFNsZL8.mjs.map} +1 -1
  64. package/dist/{reconciler-NBDSEm8k.mjs → reconciler--_-biN23.mjs} +111 -150
  65. package/dist/reconciler--_-biN23.mjs.map +1 -0
  66. package/dist/{render-string-BntLj7Xq.mjs → render-string-DaghHpLN.mjs} +1 -1
  67. package/dist/{render-string-B4h4SmK7.mjs → render-string-DtHZP0cU.mjs} +15 -11
  68. package/dist/render-string-DtHZP0cU.mjs.map +1 -0
  69. package/dist/runtime.d.mts +3 -2
  70. package/dist/runtime.mjs +3 -2
  71. package/dist/{schemes-DYt2ushj.mjs → schemes-DWQPxXAi.mjs} +2 -2
  72. package/dist/{schemes-DYt2ushj.mjs.map → schemes-DWQPxXAi.mjs.map} +1 -1
  73. package/dist/{spinner-Py8_-hn9.mjs → spinner-B50hILqx.mjs} +3 -3
  74. package/dist/{spinner-Py8_-hn9.mjs.map → spinner-B50hILqx.mjs.map} +1 -1
  75. package/dist/{spinner-CLgzJ_QF.d.mts → spinner-DN10UfF0.d.mts} +2 -2
  76. package/dist/{spinner-CLgzJ_QF.d.mts.map → spinner-DN10UfF0.d.mts.map} +1 -1
  77. package/dist/{src-Oe6x5PrS.mjs → src-B8lf1kiR.mjs} +190 -83
  78. package/dist/src-B8lf1kiR.mjs.map +1 -0
  79. package/dist/{src-Dvq-s8iD.mjs → src-BOLdi3WG.mjs} +3 -3
  80. package/dist/{src-Dvq-s8iD.mjs.map → src-BOLdi3WG.mjs.map} +1 -1
  81. package/dist/{src-B9S_woYc.mjs → src-BXeTHHlL.mjs} +20289 -23262
  82. package/dist/src-BXeTHHlL.mjs.map +1 -0
  83. package/dist/{src-WeA_J4BV.mjs → src-BqeBFB3X.mjs} +90 -47
  84. package/dist/src-BqeBFB3X.mjs.map +1 -0
  85. package/dist/{src-CbhWmUnF.mjs → src-DbqcSrhy.mjs} +1400 -1427
  86. package/dist/src-DbqcSrhy.mjs.map +1 -0
  87. package/dist/{steps-DYrzCUCK.d.mts → steps-B2kBmFpb.d.mts} +1 -1
  88. package/dist/{steps-DYrzCUCK.d.mts.map → steps-B2kBmFpb.d.mts.map} +1 -1
  89. package/dist/{svg-DhxQkz-O.mjs → svg-NmV9dgB9.mjs} +1 -1
  90. package/dist/{svg-DhxQkz-O.mjs.map → svg-NmV9dgB9.mjs.map} +1 -1
  91. package/dist/{svg-Hk7lIl4F.d.mts → svg-VUr78l5d.d.mts} +1 -1
  92. package/dist/{svg-Hk7lIl4F.d.mts.map → svg-VUr78l5d.d.mts.map} +1 -1
  93. package/dist/term.d.mts +2 -2
  94. package/dist/term.mjs +3 -3
  95. package/dist/test.d.mts +673 -0
  96. package/dist/test.d.mts.map +1 -0
  97. package/dist/test.mjs +2829 -0
  98. package/dist/test.mjs.map +1 -0
  99. package/dist/theme.d.mts +2 -2
  100. package/dist/theme.d.mts.map +1 -1
  101. package/dist/theme.mjs +3 -3
  102. package/dist/{types-Bx-XZNbE.d.mts → types-D_E0FbqA.d.mts} +1 -1
  103. package/dist/{types-Bx-XZNbE.d.mts.map → types-D_E0FbqA.d.mts.map} +1 -1
  104. package/dist/ui/animation.d.mts +2 -2
  105. package/dist/ui/animation.mjs +1 -1
  106. package/dist/ui/ansi.d.mts +1 -1
  107. package/dist/ui/ansi.mjs +1 -1
  108. package/dist/ui/cli.d.mts +3 -3
  109. package/dist/ui/cli.mjs +5 -5
  110. package/dist/ui/image.d.mts +1 -1
  111. package/dist/ui/image.mjs +1 -1
  112. package/dist/ui/progress.d.mts +4 -4
  113. package/dist/ui/progress.mjs +4 -4
  114. package/dist/ui/react.d.mts +1 -1
  115. package/dist/ui/react.mjs +2 -2
  116. package/dist/ui/react.mjs.map +1 -1
  117. package/dist/ui/recording-chrome-react.d.mts +1 -1
  118. package/dist/ui/recording-chrome-react.mjs +2 -2
  119. package/dist/ui/recording-chrome.d.mts +1 -1
  120. package/dist/ui/recording-chrome.mjs +1 -1
  121. package/dist/ui/utils.mjs +1 -1
  122. package/dist/ui/wrappers.d.mts +2 -2
  123. package/dist/ui/wrappers.mjs +1 -1
  124. package/dist/ui.d.mts +6 -6
  125. package/dist/ui.mjs +7 -7
  126. package/dist/{ansi-OYRLxxZQ.mjs → unicode-CxyxVGmB.mjs} +7317 -6909
  127. package/dist/unicode-CxyxVGmB.mjs.map +1 -0
  128. package/dist/{useLatest-DC8i7guK.d.mts → useLatest-UOvWy0ZW.d.mts} +2 -2
  129. package/dist/{useLatest-DC8i7guK.d.mts.map → useLatest-UOvWy0ZW.d.mts.map} +1 -1
  130. package/dist/{useLayout-BKsQl2Or.mjs → useLayout-D5cE8OCI.mjs} +4 -4
  131. package/dist/{useLayout-BKsQl2Or.mjs.map → useLayout-D5cE8OCI.mjs.map} +1 -1
  132. package/dist/{with-text-input-DG4f7JII.d.mts → with-text-input-DLoSCBrm.d.mts} +3 -3
  133. package/dist/{with-text-input-DG4f7JII.d.mts.map → with-text-input-DLoSCBrm.d.mts.map} +1 -1
  134. package/dist/wrap-measurer-registration-IV2HtcCd.d.mts +3106 -0
  135. package/dist/wrap-measurer-registration-IV2HtcCd.d.mts.map +1 -0
  136. package/dist/{wrapper-D7gNSsgf.mjs → wrapper-CD29afOs.mjs} +17 -37
  137. package/dist/wrapper-CD29afOs.mjs.map +1 -0
  138. package/dist/{wrappers-CypAzrMO.mjs → wrappers-CInBJm44.mjs} +6 -6
  139. package/dist/{wrappers-CypAzrMO.mjs.map → wrappers-CInBJm44.mjs.map} +1 -1
  140. package/dist/{yoga-adapter-SsEIqMc1.mjs → yoga-adapter-9uab5Qn-.mjs} +2 -2
  141. package/dist/{yoga-adapter-SsEIqMc1.mjs.map → yoga-adapter-9uab5Qn-.mjs.map} +1 -1
  142. package/dist/yoga-adapter-yqTl1aXK.mjs +2 -0
  143. package/package.json +20 -15
  144. package/dist/Text-BRf-59j2.mjs.map +0 -1
  145. package/dist/ag-BeFC4S2N.mjs.map +0 -1
  146. package/dist/ansi-OYRLxxZQ.mjs.map +0 -1
  147. package/dist/bound-term-BumfuXXW.d.mts.map +0 -1
  148. package/dist/cli-DG6zsfsS.mjs +0 -4
  149. package/dist/devtools-nmPUmYU_.mjs +0 -2
  150. package/dist/image-1nRyKa60.mjs.map +0 -1
  151. package/dist/index-2E1jYgak.d.mts.map +0 -1
  152. package/dist/index-DnuadDNL.d.mts.map +0 -1
  153. package/dist/layout-signals-Dch2EiCy.mjs.map +0 -1
  154. package/dist/mouse-events-hnbJZRwK.mjs.map +0 -1
  155. package/dist/node-BiFu8I9Y.mjs.map +0 -1
  156. package/dist/reconciler-NBDSEm8k.mjs.map +0 -1
  157. package/dist/render-string-B4h4SmK7.mjs.map +0 -1
  158. package/dist/src-B9S_woYc.mjs.map +0 -1
  159. package/dist/src-CbhWmUnF.mjs.map +0 -1
  160. package/dist/src-Oe6x5PrS.mjs.map +0 -1
  161. package/dist/src-WeA_J4BV.mjs.map +0 -1
  162. package/dist/ui/display.d.mts +0 -35
  163. package/dist/ui/display.d.mts.map +0 -1
  164. package/dist/ui/display.mjs +0 -123
  165. package/dist/ui/display.mjs.map +0 -1
  166. package/dist/ui/input.d.mts +0 -184
  167. package/dist/ui/input.d.mts.map +0 -1
  168. package/dist/ui/input.mjs +0 -283
  169. package/dist/ui/input.mjs.map +0 -1
  170. package/dist/wrapper-D7gNSsgf.mjs.map +0 -1
  171. package/dist/yoga-adapter-1ex8r0ws.mjs +0 -2
@@ -1,4 +1,4 @@
1
- import { n as EasingName, t as EasingFn } from "./easing-B0oZKDki.mjs";
1
+ import { n as EasingName, t as EasingFn } from "./easing-C5MrdO7V.mjs";
2
2
 
3
3
  //#region packages/ag-react/src/ui/animation/useAnimation.d.ts
4
4
  interface UseAnimationOptions {
@@ -131,4 +131,4 @@ declare function useLatest<T>(value: T): {
131
131
  };
132
132
  //#endregion
133
133
  export { useTransition as a, useAnimation as c, UseTransitionOptions as i, useTimeout as n, UseAnimationOptions as o, useInterval as r, UseAnimationResult as s, useLatest as t };
134
- //# sourceMappingURL=useLatest-DC8i7guK.d.mts.map
134
+ //# sourceMappingURL=useLatest-UOvWy0ZW.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLatest-DC8i7guK.d.mts","names":[],"sources":["../packages/ag-react/src/ui/animation/useAnimation.ts","../packages/ag-react/src/ui/animation/useTransition.ts","../packages/ag-react/src/ui/animation/useInterval.ts","../packages/ag-react/src/ui/animation/useTimeout.ts","../packages/ag-react/src/ui/animation/useLatest.ts"],"mappings":";;;UAeiB,mBAAA;EAIN;EAFT,QAAA;EAIA;EAFA,MAAA,GAAS,UAAA,GAAa,QAAA;EAMtB;EAJA,KAAA;EAIO;EAFP,UAAA;EAKiC;EAHjC,OAAA;AAAA;AAAA,UAGe,kBAAA;EAIf;EAFA,KAAA;EAIK;EAFL,WAAA;EA2Bc;EAzBd,KAAA;AAAA;;;;;;;;;;ACnBF;;iBD4CgB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,kBAAA;;;UC5C3C,oBAAA;EDIN;ECFT,QAAA;EDIA;ECFA,MAAA,GAAS,UAAA,GAAa,QAAA;AAAA;;;ADSxB;;;;;;;;;AA+BA;;;;iBCXgB,aAAA,CAAc,WAAA,UAAqB,OAAA,GAAU,oBAAA;;;;;;ADjC7D;;;;;;;;;;;;;iBEQgB,WAAA,CAAY,QAAA,cAAsB,EAAA,UAAY,OAAA;;;;;;AFR9D;;;;;;;;;;;;;AAaA;;;iBGFgB,UAAA,CACd,QAAA,cACA,EAAA,UACA,OAAA;EACG,KAAA;EAAmB,KAAA;AAAA;;;;;;AHfxB;;;;;;;;;;;;;AAaA;;;;;;;iBIEgB,SAAA,GAAA,CAAa,KAAA,EAAO,CAAA;EAAA,SAAe,OAAA,EAAS,CAAA;AAAA"}
1
+ {"version":3,"file":"useLatest-UOvWy0ZW.d.mts","names":[],"sources":["../packages/ag-react/src/ui/animation/useAnimation.ts","../packages/ag-react/src/ui/animation/useTransition.ts","../packages/ag-react/src/ui/animation/useInterval.ts","../packages/ag-react/src/ui/animation/useTimeout.ts","../packages/ag-react/src/ui/animation/useLatest.ts"],"mappings":";;;UAeiB,mBAAA;EAIN;EAFT,QAAA;EAIA;EAFA,MAAA,GAAS,UAAA,GAAa,QAAA;EAMtB;EAJA,KAAA;EAIO;EAFP,UAAA;EAKiC;EAHjC,OAAA;AAAA;AAAA,UAGe,kBAAA;EAIf;EAFA,KAAA;EAIK;EAFL,WAAA;EA2Bc;EAzBd,KAAA;AAAA;;;;;;;;;;ACnBF;;iBD4CgB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,kBAAA;;;UC5C3C,oBAAA;EDIN;ECFT,QAAA;EDIA;ECFA,MAAA,GAAS,UAAA,GAAa,QAAA;AAAA;;;ADSxB;;;;;;;;;AA+BA;;;;iBCXgB,aAAA,CAAc,WAAA,UAAqB,OAAA,GAAU,oBAAA;;;;;;ADjC7D;;;;;;;;;;;;;iBEQgB,WAAA,CAAY,QAAA,cAAsB,EAAA,UAAY,OAAA;;;;;;AFR9D;;;;;;;;;;;;;AAaA;;;iBGFgB,UAAA,CACd,QAAA,cACA,EAAA,UACA,OAAA;EACG,KAAA;EAAmB,KAAA;AAAA;;;;;;AHfxB;;;;;;;;;;;;;AAaA;;;;;;;iBIEgB,SAAA,GAAA,CAAa,KAAA,EAAO,CAAA;EAAA,SAAe,OAAA,EAAS,CAAA;AAAA"}
@@ -1,6 +1,6 @@
1
- import { r as effect } from "./src-WeA_J4BV.mjs";
2
- import { a as NodeContext } from "./context-BU5LkkIy.mjs";
3
- import { _ as rectEqual, l as markObservedLayoutSignal, o as getLayoutSignals } from "./layout-signals-Dch2EiCy.mjs";
1
+ import { r as effect } from "./src-BqeBFB3X.mjs";
2
+ import { _ as rectEqual, l as markObservedLayoutSignal, o as getLayoutSignals } from "./layout-signals-CGYbHmxy.mjs";
3
+ import { a as NodeContext } from "./context-CEhuD1R_.mjs";
4
4
  import { useContext, useLayoutEffect, useReducer, useRef } from "react";
5
5
  //#region packages/ag-react/src/hooks/useLayout.ts
6
6
  /**
@@ -421,4 +421,4 @@ function useOnScreenRectCommitted(cb) {
421
421
  //#endregion
422
422
  export { useOnBoxRectCommitted as a, useScreenRect as c, useScrollRectInFlight as d, useBoxSize as i, useScreenRectInFlight as l, useBoxRectDangerously as n, useOnScreenRectCommitted as o, useBoxRectInFlight as r, useOnScrollRectCommitted as s, useBoxRect as t, useScrollRect as u };
423
423
 
424
- //# sourceMappingURL=useLayout-BKsQl2Or.mjs.map
424
+ //# sourceMappingURL=useLayout-D5cE8OCI.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLayout-BKsQl2Or.mjs","names":[],"sources":["../packages/ag-react/src/hooks/useLayout.ts"],"sourcesContent":["/**\n * Layout Hooks — three coordinate systems for positioning in silvery.\n *\n * Every silvery node has three rects that differ only by how scroll and\n * sticky offsets are applied. Pick the one that matches your use case:\n *\n * - `useBoxRect()` — layout position (border-box sized, minus padding/border).\n * Use for responsive sizing inside a component. Matches\n * CSS `clientWidth`/`clientHeight` for the content area.\n * - `useScrollRect()` — scroll-adjusted position, **pre** sticky clamping.\n * Use when you need the \"natural\" position of a node\n * in scrolled coordinates (can go off-screen).\n * - `useScreenRect()` — actual paint position on the terminal screen.\n * Use for hit testing, cursor positioning, and\n * cross-component visual navigation. The CSS\n * `getBoundingClientRect()` analogue.\n *\n * ## Deferred semantics (the only contract)\n *\n * Each hook returns the rect as of the **most recent committed layout** —\n * the value as of the last event-batch commit boundary. Within a single\n * batch, the returned value is invariant across every convergence pass;\n * React renders see one value per batch. After the batch's commit boundary\n * fires, the next batch sees the new value.\n *\n * This is the structural fix for the \"render reads useBoxRect AND writes\n * a layout-affecting prop based on it\" feedback loop. Under the in-flight\n * model that preceded this hook (pre 2026-05-06), the read returned the\n * latest measurement during the same batch, which could differ between\n * the first and second convergence passes — causing the write to flip\n * between branches and the loop to ping-pong until `MAX_CONVERGENCE_PASSES`\n * capped it. Under deferred semantics the read is invariant for the\n * batch, so the loop completes in one pass.\n *\n * **One-frame-late by design.** A component that mounts shows the\n * empty-rect fallback (`{ x: 0, y: 0, width: 0, height: 0 }`) on its\n * first render and the real rect on the next commit boundary. Layout\n * effects that run on the second render see the real rect and can write\n * positioned terminal escapes (Image, decorations) into the next\n * paintFrame.\n *\n * Components that need same-frame measurements must read `node.boxRect`\n * etc. directly via `useAgNode()` and gate on `useLayoutEffect` —\n * recommended only for leaf primitives in the silvery framework itself.\n *\n * For breakpoint logic, prefer `useResponsiveValue()` or\n * `useResponsiveBoxProps()` — bucketing into stable zones gives more\n * predictable behavior than branching on raw widths.\n *\n * See bead `@km/silvery/use-deferred-box-rect-and-post-commit-observers`.\n */\n\nimport { useContext, useLayoutEffect, useReducer, useRef } from \"react\"\nimport { effect } from \"@silvery/signals\"\nimport { NodeContext } from \"../context\"\nimport { type AgNode, type BoxProps, type Rect, rectEqual } from \"@silvery/ag/types\"\nimport {\n getLayoutSignals,\n markObservedLayoutSignal,\n type ObservedLayoutSignalKey,\n} from \"@silvery/ag/layout-signals\"\n\nexport type { Rect }\n\nconst EMPTY_RECT: Rect = { x: 0, y: 0, width: 0, height: 0 }\nconst EMPTY_SIZE: BoxSize = { width: 0, height: 0 }\n\nexport interface BoxSize {\n width: number\n height: number\n}\n\n/**\n * Get the inner content dimensions of a node (border-box minus padding and border).\n * This is the space available for the node's children.\n *\n * `boxRect` is passed in explicitly so the helper derives the inner rect\n * from the committed signal value rather than re-reading `node.boxRect`\n * (which holds the in-flight value mid-batch).\n */\nfunction deriveInnerRect(node: AgNode, boxRect: Rect | null | undefined): Rect | null {\n if (!boxRect) return null\n\n const props = node.props as BoxProps\n if (!props || node.type === \"silvery-text\") return boxRect\n\n // Compute padding\n const pTop = props.paddingTop ?? props.paddingY ?? props.padding ?? 0\n const pBottom = props.paddingBottom ?? props.paddingY ?? props.padding ?? 0\n const pLeft = props.paddingLeft ?? props.paddingX ?? props.padding ?? 0\n const pRight = props.paddingRight ?? props.paddingX ?? props.padding ?? 0\n\n // Compute border (1px per side if borderStyle is set)\n let bTop = 0\n let bBottom = 0\n let bLeft = 0\n let bRight = 0\n if (props.borderStyle) {\n bTop = props.borderTop !== false ? 1 : 0\n bBottom = props.borderBottom !== false ? 1 : 0\n bLeft = props.borderLeft !== false ? 1 : 0\n bRight = props.borderRight !== false ? 1 : 0\n }\n\n return {\n x: boxRect.x + pLeft + bLeft,\n y: boxRect.y + pTop + bTop,\n width: Math.max(0, boxRect.width - pLeft - pRight - bLeft - bRight),\n height: Math.max(0, boxRect.height - pTop - pBottom - bTop - bBottom),\n }\n}\n\n/** Selector that picks which committed rect signal to subscribe to. */\ntype CommittedRectSignalKey = \"boxRectCommitted\" | \"scrollRectCommitted\" | \"screenRectCommitted\"\n\n/** Selector that picks which in-flight rect signal to subscribe to. */\ntype InFlightRectSignalKey = \"boxRect\" | \"scrollRect\" | \"screenRect\"\n\nconst COMMITTED_RECT_OBSERVED_KEY: Record<CommittedRectSignalKey, ObservedLayoutSignalKey> = {\n boxRectCommitted: \"boxRect\",\n scrollRectCommitted: \"scrollRect\",\n screenRectCommitted: \"screenRect\",\n}\n\nconst IN_FLIGHT_RECT_OBSERVED_KEY: Record<InFlightRectSignalKey, ObservedLayoutSignalKey> = {\n boxRect: \"boxRect\",\n scrollRect: \"scrollRect\",\n screenRect: \"screenRect\",\n}\n\n/**\n * Reactive rect hook (deferred): subscribes to a committed rect signal and\n * re-renders when the value advances at a commit boundary. Returns the\n * rect derived from the committed value via `getCommittedRect`.\n *\n * Within a single event batch the committed signal does not change — every\n * convergence pass sees the same value, so a render that reads useBoxRect\n * and writes a layout-affecting prop converges in one pass. After the\n * batch's commit boundary (handled by the runtime via\n * `commitLayoutSnapshot`), the next batch's first render sees the new\n * value.\n */\nfunction useReactiveRect(\n getCommittedRect: (committed: Rect | null, node: AgNode) => Rect | null | undefined,\n committedSignalKey: CommittedRectSignalKey,\n): Rect {\n const node = useContext(NodeContext)\n const [, forceUpdate] = useReducer((x: number) => x + 1, 0)\n const prevRef = useRef<Rect | null>(null)\n\n useLayoutEffect(() => {\n if (!node) return\n\n markObservedLayoutSignal(node, COMMITTED_RECT_OBSERVED_KEY[committedSignalKey])\n const signals = getLayoutSignals(node)\n const rectSignal = signals[committedSignalKey]\n\n // effect() subscribes to the COMMITTED signal — re-runs when the signal\n // value changes. The committed signal advances only at event-batch\n // commit boundaries (see `commitLayoutSnapshot`), so this fires at most\n // once per batch — never mid-batch — making it impossible to form a\n // feedback edge with a render that branches on the read value.\n const dispose = effect(() => {\n const committed = rectSignal()\n const next = getCommittedRect(committed, node) ?? null\n if (!rectEqual(prevRef.current, next)) {\n prevRef.current = next\n forceUpdate()\n }\n })\n\n return dispose\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node])\n\n if (!node) return EMPTY_RECT\n // Synchronous read (called during render): use the committed signal's\n // current value, NOT `node.boxRect` etc. The in-flight rect on the node\n // may have been updated by an earlier convergence pass within this batch\n // — reading it would re-introduce the feedback edge this hook exists to\n // eliminate. The committed signal is invariant for the batch.\n markObservedLayoutSignal(node, COMMITTED_RECT_OBSERVED_KEY[committedSignalKey])\n const signals = getLayoutSignals(node)\n const committed = signals[committedSignalKey]()\n return getCommittedRect(committed, node) ?? EMPTY_RECT\n}\n\n// ============================================================================\n// boxRect — layout position (border-box minus padding/border)\n// ============================================================================\n\n/**\n * **DANGEROUS — measurement read on the render path.** Prefer a declarative\n * primitive (`<Box fitWidth>`, `useResponsiveBoxProps`, `useResponsiveValue`,\n * `useOnBoxRectCommitted`) before reaching for this hook.\n *\n * Returns the inner content dimensions for the current component's nearest\n * Box, as of the most recent committed layout. Width and height reflect\n * the space available for children (border-box minus padding and border),\n * like CSS `clientWidth`/`clientHeight`.\n *\n * ```tsx\n * function Header() {\n * const { width } = useBoxRectDangerously()\n * return <Text>{'='.repeat(Math.max(0, width))}</Text>\n * }\n * ```\n *\n * On first render returns `{ x: 0, y: 0, width: 0, height: 0 }`. After the\n * first commit boundary, automatically re-renders with the measured\n * dimensions. This **first-paint zero-rect transition** is the social cost\n * the rename announces — components that branch layout on this hook see a\n * flush-left / collapsed first paint, then re-flow when the real rect\n * commits one event-loop tick later. Visible jank under streaming / dynamic\n * mount / SIGWINCH burst.\n *\n * Use only when:\n * - You need a measurement read in JS control flow (animation, autoscroll\n * thresholds, hit-testing) that **doesn't drive layout-affecting props**.\n * - No declarative primitive covers the case.\n *\n * Deferred semantics — see this file's docstring for the contract and the\n * one-frame-late behavior.\n *\n * Bead: `@km/silvery/responsive-layout-architecture-reframe` (Phase A.1\n * lands this rename; the full Phase A migrates each consumer to a\n * declarative primitive or, where genuinely needed, to a Suspense-friendly\n * `Promise<Rect>` form coordinated via `RectReadBarrier`).\n */\nexport function useBoxRectDangerously(): Rect {\n return useReactiveRect((committed, node) => deriveInnerRect(node, committed), \"boxRectCommitted\")\n}\n\n/**\n * @deprecated Renamed to `useBoxRectDangerously`. The original name read as\n * \"the normal hook for getting your rect\" — exactly the framing the Phase\n * A.1 rename is intended to break. App authors should reach for declarative\n * primitives first; this alias remains for one release cycle and logs a\n * dev-time warning per call site. Will be removed in the next major.\n *\n * Bead: `@km/silvery/responsive-layout-architecture-reframe`.\n */\nexport function useBoxRect(): Rect {\n // Deprecation warning fires once per call site in development. Skipped in\n // production (won't ship) AND test (vitest's fail-on-console policy would\n // trip on every test that exercises the legacy alias — including the very\n // tests that verify backward-compat). Silvery's own internal call sites\n // are migrated to `useBoxRectDangerously` as part of Phase A.1, so test\n // suites don't see the warning either way.\n if (process.env.NODE_ENV !== \"production\" && process.env.NODE_ENV !== \"test\") {\n warnUseBoxRectDeprecation()\n }\n return useReactiveRect((committed, node) => deriveInnerRect(node, committed), \"boxRectCommitted\")\n}\n\n/**\n * Internal dimensions-only variant of the deferred box rect read.\n *\n * This is for framework primitives that build width/height-derived text\n * (Divider, ProgressBar, TextArea wrapping) but do not care where their\n * parent sits on screen. It subscribes to the same committed boxRect signal\n * as `useBoxRect()`, but only re-renders when the derived inner\n * `{width,height}` changes. Scrolling and virtual-window spacer movement\n * often change x/y without changing dimensions; full-rect subscriptions wake\n * these primitives on every such frame and steal scroll budget.\n */\nexport function useBoxSize(): BoxSize {\n const node = useContext(NodeContext)\n const [, forceUpdate] = useReducer((x: number) => x + 1, 0)\n const prevRef = useRef<BoxSize | null>(null)\n\n useLayoutEffect(() => {\n if (!node) return\n\n markObservedLayoutSignal(node, \"boxSize\")\n const signals = getLayoutSignals(node)\n\n const dispose = effect(() => {\n const rect = deriveInnerRect(node, signals.boxRectCommitted())\n const next = rect ? { width: rect.width, height: rect.height } : EMPTY_SIZE\n const prev = prevRef.current\n if (!prev || prev.width !== next.width || prev.height !== next.height) {\n prevRef.current = next\n forceUpdate()\n }\n })\n\n return dispose\n }, [node])\n\n if (!node) return EMPTY_SIZE\n markObservedLayoutSignal(node, \"boxSize\")\n const rect = deriveInnerRect(node, getLayoutSignals(node).boxRectCommitted())\n return rect ? { width: rect.width, height: rect.height } : EMPTY_SIZE\n}\n\nconst useBoxRectWarnedCallSites = new Set<string>()\n\nfunction warnUseBoxRectDeprecation(): void {\n // Dedupe per-call-site so the warning fires once per source location, not\n // once per render. The first stack frame outside this file is the consumer.\n const stack = new Error().stack ?? \"\"\n const lines = stack.split(\"\\n\")\n let consumerFrame = \"\"\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\"\n if (!line.includes(\"useLayout.ts\") && line.trim().startsWith(\"at \")) {\n consumerFrame = line.trim()\n break\n }\n }\n const key = consumerFrame || \"<unknown>\"\n if (useBoxRectWarnedCallSites.has(key)) return\n useBoxRectWarnedCallSites.add(key)\n // eslint-disable-next-line no-console\n console.warn(\n `[silvery] useBoxRect() is deprecated — rename to useBoxRectDangerously(), or migrate to a declarative primitive ` +\n `(<Box fitWidth>, useResponsiveBoxProps, useResponsiveValue, useOnBoxRectCommitted). ` +\n `See @km/silvery/responsive-layout-architecture-reframe. Call site: ${key}`,\n )\n}\n\n// ============================================================================\n// scrollRect — scroll-adjusted position (pre-sticky clamping)\n// ============================================================================\n\n/**\n * Returns the scroll-adjusted position for the current component, as of\n * the most recent committed layout.\n *\n * This is the node's position in scroll coordinates, *before* sticky\n * clamping. For non-sticky nodes it equals `useScreenRect()`. For sticky\n * nodes, the scrollRect reflects where the node would be without sticky\n * adjustment — so it can go off-screen (negative y, etc.) when scrolled\n * past.\n *\n * ```tsx\n * function Card({ id }) {\n * const { y } = useScrollRect()\n * return <Box>Scroll y: {y}</Box>\n * }\n * ```\n *\n * Deferred semantics — see this file's docstring.\n */\nexport function useScrollRect(): Rect {\n return useReactiveRect((committed) => committed, \"scrollRectCommitted\")\n}\n\n// ============================================================================\n// screenRect — actual paint position on the terminal screen\n// ============================================================================\n\n/**\n * Returns the actual paint position on the terminal screen as of the most\n * recent committed layout — the silvery analogue of\n * `getBoundingClientRect()`.\n *\n * For non-sticky nodes this equals `useScrollRect()`. For sticky nodes\n * (`position=\"sticky\"`), it reflects the clamped position where pixels\n * actually land on screen.\n *\n * ```tsx\n * function StickyHeader() {\n * const { y } = useScreenRect()\n * return <Box position=\"sticky\" stickyTop={0}>Header at row {y}</Box>\n * }\n * ```\n *\n * Deferred semantics — see this file's docstring.\n */\nexport function useScreenRect(): Rect {\n return useReactiveRect((committed) => committed, \"screenRectCommitted\")\n}\n\n// ============================================================================\n// In-flight escape hatches — read the live (mid-batch) rect signal\n// ============================================================================\n//\n// The reactive `useBoxRect()` / `useScrollRect()` / `useScreenRect()` hooks\n// return the COMMITTED rect (one frame deferred) — see this file's docstring\n// for the contract. The committed-only contract eliminates render → write →\n// re-measure feedback loops by construction, but it forces components that\n// genuinely need first-paint dimensions to wait one frame.\n//\n// `useBoxRectInFlight()` / `useScrollRectInFlight()` / `useScreenRectInFlight()`\n// subscribe to the IN-FLIGHT signal — the rect as written by the most recent\n// layout pass within the current convergence cycle. The value can change\n// between convergence passes within a single event batch, so a render that\n// reads it AND writes a layout-affecting prop CAN form a feedback edge.\n//\n// **For silvery framework internals only.** Image, useCursor, useGridPosition,\n// and ListView's viewport-tracking path are the real consumers — leaf\n// primitives whose first-paint measurement is critical for scroll, decoration,\n// or absolute-positioning math, and which don't drive layout-affecting props\n// back into the React tree. (Lane snapping, once an in-flight consumer here,\n// now lives in the engine as the `fitWidth` Box prop and doesn't reach for\n// these hooks at all.)\n//\n// **Lint-gated.** App code (silvercode, km-tui, downstream consumers) must\n// not import these hooks — the ESLint rule `silvery/no-in-flight-rect-in-app`\n// blocks imports from outside `vendor/silvery/`. App code that needs\n// first-paint layout decisions must use `useResponsiveBoxProps` /\n// `useResponsiveValue` (declarative, no measurement reads) — the path\n// documented in [The Silvery Way §2](../../docs/guide/the-silvery-way.md).\n//\n// **Why both forms exist.** The deferred form is the safe default; the\n// in-flight form is an explicit escape hatch acknowledging that silvery's\n// own primitives can't always wait one frame for measurement. Naming the\n// escape hatch `*InFlight` makes the cost legible at the call site.\n//\n// See bead `@km/silvery/usebox-rect-deferred-only-breaks-first-paint`.\n\n/**\n * In-flight reactive rect hook (escape hatch): subscribes to the LIVE rect\n * signal — the value as written by the most recent layout pass within the\n * current convergence cycle. Re-renders when the in-flight value advances,\n * which can happen multiple times per event batch as the convergence loop\n * iterates.\n *\n * Use only inside silvery framework internals where first-paint measurement\n * is required and the consumer does not write layout-affecting props\n * derived from the read. App code must use the deferred form\n * (`useBoxRect()` / `useScrollRect()` / `useScreenRect()`) or\n * `useResponsiveBoxProps`/`useResponsiveValue` instead.\n */\nfunction useReactiveRectInFlight(\n getDerivedRect: (raw: Rect | null, node: AgNode) => Rect | null | undefined,\n inFlightSignalKey: InFlightRectSignalKey,\n): Rect {\n const node = useContext(NodeContext)\n const [, forceUpdate] = useReducer((x: number) => x + 1, 0)\n const prevRef = useRef<Rect | null>(null)\n\n useLayoutEffect(() => {\n if (!node) return\n\n markObservedLayoutSignal(node, IN_FLIGHT_RECT_OBSERVED_KEY[inFlightSignalKey])\n const signals = getLayoutSignals(node)\n const rectSignal = signals[inFlightSignalKey]\n\n // effect() subscribes to the IN-FLIGHT signal — re-runs whenever the\n // signal advances, including mid-batch as the convergence loop iterates.\n // This is intentionally permissive vs the committed form; consumers that\n // can't accept first-paint zero-rect (Image, useCursor, useGridPosition)\n // opt in via this hook.\n const dispose = effect(() => {\n const raw = rectSignal()\n const next = getDerivedRect(raw, node) ?? null\n if (!rectEqual(prevRef.current, next)) {\n prevRef.current = next\n forceUpdate()\n }\n })\n\n return dispose\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node])\n\n if (!node) return EMPTY_RECT\n // Synchronous read (called during render): use the in-flight signal\n // directly (NOT `node.boxRect` — that bypasses the reactive subscription\n // edge and would let the render see one value while the effect sees\n // another). The in-flight signal value reflects the most recent layout\n // pass; it may differ between convergence passes within a batch.\n markObservedLayoutSignal(node, IN_FLIGHT_RECT_OBSERVED_KEY[inFlightSignalKey])\n const signals = getLayoutSignals(node)\n const raw = signals[inFlightSignalKey]()\n return getDerivedRect(raw, node) ?? EMPTY_RECT\n}\n\n/**\n * Returns the inner content dimensions of the current Box from the IN-FLIGHT\n * signal — the value as of the most recent layout pass, which may change\n * between convergence passes within an event batch.\n *\n * Silvery framework internals only — app code must use {@link useBoxRect}\n * (deferred) or `useResponsiveBoxProps`/`useResponsiveValue` instead.\n *\n * Unlike {@link useBoxRect} (the deferred form), this hook returns the\n * measured value on the first render after layout — there is no one-frame\n * fallback. The cost is that a render reading this hook AND writing a\n * layout-affecting prop can form a convergence-loop feedback edge; the\n * lint rule `silvery/no-in-flight-rect-in-app` enforces the call-site\n * scope.\n */\nexport function useBoxRectInFlight(): Rect {\n return useReactiveRectInFlight((raw, node) => deriveInnerRect(node, raw), \"boxRect\")\n}\n\n/**\n * Returns the scroll-adjusted position from the IN-FLIGHT signal — the\n * value as of the most recent layout pass, which may change between\n * convergence passes within an event batch.\n *\n * Silvery framework internals only — see {@link useBoxRectInFlight} for\n * the contract and the lint rule that gates app-code use.\n */\nexport function useScrollRectInFlight(): Rect {\n return useReactiveRectInFlight((raw) => raw, \"scrollRect\")\n}\n\n/**\n * Returns the actual paint position from the IN-FLIGHT signal — the value\n * as of the most recent layout pass, which may change between convergence\n * passes within an event batch.\n *\n * Silvery framework internals only — see {@link useBoxRectInFlight} for\n * the contract and the lint rule that gates app-code use.\n */\nexport function useScreenRectInFlight(): Rect {\n return useReactiveRectInFlight((raw) => raw, \"screenRect\")\n}\n\n// ============================================================================\n// Callback observers — fire on commit boundary without triggering re-render\n// ============================================================================\n//\n// The reactive `useBoxRect()` / `useScrollRect()` / `useScreenRect()` hooks\n// re-render the consuming component every time the committed rect advances.\n// For hot paths where the rect change should NOT re-render the consumer\n// (cursor positioning, grid registry, decoration emission), the callback\n// observers below subscribe directly to the committed signal and invoke\n// `cb(rect)` at every commit boundary — no React state churn, no re-render.\n//\n// Restored 2026-05-10 to address the perf regression introduced by removing\n// the callback overload from `useBoxRect()` in silvery `63938779b6`. The\n// previous callback form was `useBoxRect((rect) => …)` overloaded on the\n// reactive hook; that fused two distinct contracts into one signature. The\n// observer hooks below split them: reactive read + commit-boundary observer.\n\n/**\n * Subscribes to the committed rect signal and fires `cb(rect)` at each\n * commit boundary, **without** triggering a re-render of the consumer.\n *\n * Use for hot paths where a rect change drives an imperative side effect\n * (cursor store update, registry write, ANSI emission) and there is no\n * render path that needs to reflect the rect.\n *\n * The callback is invoked synchronously from a commit-boundary effect(),\n * with the derived rect (`getDerivedRect` applied to the committed signal\n * value). It is NOT invoked when the derived rect is null. The caller may\n * close over component state via refs; see `useCursor` / `useGridPosition`\n * for canonical patterns.\n */\nfunction useOnRectCommitted(\n cb: (rect: Rect) => void,\n getDerivedRect: (committed: Rect | null, node: AgNode) => Rect | null | undefined,\n committedSignalKey: CommittedRectSignalKey,\n): void {\n const node = useContext(NodeContext)\n const cbRef = useRef(cb)\n cbRef.current = cb\n\n useLayoutEffect(() => {\n if (!node) return\n\n const signals = getLayoutSignals(node)\n const rectSignal = signals[committedSignalKey]\n let prev: Rect | null = null\n\n const dispose = effect(() => {\n const committed = rectSignal()\n const next = getDerivedRect(committed, node) ?? null\n if (next == null) return\n if (rectEqual(prev, next)) return\n prev = next\n cbRef.current(next)\n })\n\n return dispose\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node])\n}\n\n/**\n * Subscribes to the committed boxRect (inner content) and fires `cb` at\n * each commit boundary without re-rendering. See {@link useBoxRect} for\n * the deferred-rect contract; this is the observer form.\n */\nexport function useOnBoxRectCommitted(cb: (rect: Rect) => void): void {\n useOnRectCommitted(cb, (committed, node) => deriveInnerRect(node, committed), \"boxRectCommitted\")\n}\n\n/**\n * Subscribes to the committed scrollRect and fires `cb` at each commit\n * boundary without re-rendering.\n */\nexport function useOnScrollRectCommitted(cb: (rect: Rect) => void): void {\n useOnRectCommitted(cb, (committed) => committed, \"scrollRectCommitted\")\n}\n\n/**\n * Subscribes to the committed screenRect and fires `cb` at each commit\n * boundary without re-rendering.\n */\nexport function useOnScreenRectCommitted(cb: (rect: Rect) => void): void {\n useOnRectCommitted(cb, (committed) => committed, \"screenRectCommitted\")\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useLayout-D5cE8OCI.mjs","names":[],"sources":["../packages/ag-react/src/hooks/useLayout.ts"],"sourcesContent":["/**\n * Layout Hooks — three coordinate systems for positioning in silvery.\n *\n * Every silvery node has three rects that differ only by how scroll and\n * sticky offsets are applied. Pick the one that matches your use case:\n *\n * - `useBoxRect()` — layout position (border-box sized, minus padding/border).\n * Use for responsive sizing inside a component. Matches\n * CSS `clientWidth`/`clientHeight` for the content area.\n * - `useScrollRect()` — scroll-adjusted position, **pre** sticky clamping.\n * Use when you need the \"natural\" position of a node\n * in scrolled coordinates (can go off-screen).\n * - `useScreenRect()` — actual paint position on the terminal screen.\n * Use for hit testing, cursor positioning, and\n * cross-component visual navigation. The CSS\n * `getBoundingClientRect()` analogue.\n *\n * ## Deferred semantics (the only contract)\n *\n * Each hook returns the rect as of the **most recent committed layout** —\n * the value as of the last event-batch commit boundary. Within a single\n * batch, the returned value is invariant across every convergence pass;\n * React renders see one value per batch. After the batch's commit boundary\n * fires, the next batch sees the new value.\n *\n * This is the structural fix for the \"render reads useBoxRect AND writes\n * a layout-affecting prop based on it\" feedback loop. Under the in-flight\n * model that preceded this hook (pre 2026-05-06), the read returned the\n * latest measurement during the same batch, which could differ between\n * the first and second convergence passes — causing the write to flip\n * between branches and the loop to ping-pong until `MAX_CONVERGENCE_PASSES`\n * capped it. Under deferred semantics the read is invariant for the\n * batch, so the loop completes in one pass.\n *\n * **One-frame-late by design.** A component that mounts shows the\n * empty-rect fallback (`{ x: 0, y: 0, width: 0, height: 0 }`) on its\n * first render and the real rect on the next commit boundary. Layout\n * effects that run on the second render see the real rect and can write\n * positioned terminal escapes (Image, decorations) into the next\n * paintFrame.\n *\n * Components that need same-frame measurements must read `node.boxRect`\n * etc. directly via `useAgNode()` and gate on `useLayoutEffect` —\n * recommended only for leaf primitives in the silvery framework itself.\n *\n * For breakpoint logic, prefer `useResponsiveValue()` or\n * `useResponsiveBoxProps()` — bucketing into stable zones gives more\n * predictable behavior than branching on raw widths.\n *\n * See bead `@km/silvery/use-deferred-box-rect-and-post-commit-observers`.\n */\n\nimport { useContext, useLayoutEffect, useReducer, useRef } from \"react\"\nimport { effect } from \"@silvery/signals\"\nimport { NodeContext } from \"../context\"\nimport { type AgNode, type BoxProps, type Rect, rectEqual } from \"@silvery/ag/types\"\nimport {\n getLayoutSignals,\n markObservedLayoutSignal,\n type ObservedLayoutSignalKey,\n} from \"@silvery/ag/layout-signals\"\n\nexport type { Rect }\n\nconst EMPTY_RECT: Rect = { x: 0, y: 0, width: 0, height: 0 }\nconst EMPTY_SIZE: BoxSize = { width: 0, height: 0 }\n\nexport interface BoxSize {\n width: number\n height: number\n}\n\n/**\n * Get the inner content dimensions of a node (border-box minus padding and border).\n * This is the space available for the node's children.\n *\n * `boxRect` is passed in explicitly so the helper derives the inner rect\n * from the committed signal value rather than re-reading `node.boxRect`\n * (which holds the in-flight value mid-batch).\n */\nfunction deriveInnerRect(node: AgNode, boxRect: Rect | null | undefined): Rect | null {\n if (!boxRect) return null\n\n const props = node.props as BoxProps\n if (!props || node.type === \"silvery-text\") return boxRect\n\n // Compute padding\n const pTop = props.paddingTop ?? props.paddingY ?? props.padding ?? 0\n const pBottom = props.paddingBottom ?? props.paddingY ?? props.padding ?? 0\n const pLeft = props.paddingLeft ?? props.paddingX ?? props.padding ?? 0\n const pRight = props.paddingRight ?? props.paddingX ?? props.padding ?? 0\n\n // Compute border (1px per side if borderStyle is set)\n let bTop = 0\n let bBottom = 0\n let bLeft = 0\n let bRight = 0\n if (props.borderStyle) {\n bTop = props.borderTop !== false ? 1 : 0\n bBottom = props.borderBottom !== false ? 1 : 0\n bLeft = props.borderLeft !== false ? 1 : 0\n bRight = props.borderRight !== false ? 1 : 0\n }\n\n return {\n x: boxRect.x + pLeft + bLeft,\n y: boxRect.y + pTop + bTop,\n width: Math.max(0, boxRect.width - pLeft - pRight - bLeft - bRight),\n height: Math.max(0, boxRect.height - pTop - pBottom - bTop - bBottom),\n }\n}\n\n/** Selector that picks which committed rect signal to subscribe to. */\ntype CommittedRectSignalKey = \"boxRectCommitted\" | \"scrollRectCommitted\" | \"screenRectCommitted\"\n\n/** Selector that picks which in-flight rect signal to subscribe to. */\ntype InFlightRectSignalKey = \"boxRect\" | \"scrollRect\" | \"screenRect\"\n\nconst COMMITTED_RECT_OBSERVED_KEY: Record<CommittedRectSignalKey, ObservedLayoutSignalKey> = {\n boxRectCommitted: \"boxRect\",\n scrollRectCommitted: \"scrollRect\",\n screenRectCommitted: \"screenRect\",\n}\n\nconst IN_FLIGHT_RECT_OBSERVED_KEY: Record<InFlightRectSignalKey, ObservedLayoutSignalKey> = {\n boxRect: \"boxRect\",\n scrollRect: \"scrollRect\",\n screenRect: \"screenRect\",\n}\n\n/**\n * Reactive rect hook (deferred): subscribes to a committed rect signal and\n * re-renders when the value advances at a commit boundary. Returns the\n * rect derived from the committed value via `getCommittedRect`.\n *\n * Within a single event batch the committed signal does not change — every\n * convergence pass sees the same value, so a render that reads useBoxRect\n * and writes a layout-affecting prop converges in one pass. After the\n * batch's commit boundary (handled by the runtime via\n * `commitLayoutSnapshot`), the next batch's first render sees the new\n * value.\n */\nfunction useReactiveRect(\n getCommittedRect: (committed: Rect | null, node: AgNode) => Rect | null | undefined,\n committedSignalKey: CommittedRectSignalKey,\n): Rect {\n const node = useContext(NodeContext)\n const [, forceUpdate] = useReducer((x: number) => x + 1, 0)\n const prevRef = useRef<Rect | null>(null)\n\n useLayoutEffect(() => {\n if (!node) return\n\n markObservedLayoutSignal(node, COMMITTED_RECT_OBSERVED_KEY[committedSignalKey])\n const signals = getLayoutSignals(node)\n const rectSignal = signals[committedSignalKey]\n\n // effect() subscribes to the COMMITTED signal — re-runs when the signal\n // value changes. The committed signal advances only at event-batch\n // commit boundaries (see `commitLayoutSnapshot`), so this fires at most\n // once per batch — never mid-batch — making it impossible to form a\n // feedback edge with a render that branches on the read value.\n const dispose = effect(() => {\n const committed = rectSignal()\n const next = getCommittedRect(committed, node) ?? null\n if (!rectEqual(prevRef.current, next)) {\n prevRef.current = next\n forceUpdate()\n }\n })\n\n return dispose\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node])\n\n if (!node) return EMPTY_RECT\n // Synchronous read (called during render): use the committed signal's\n // current value, NOT `node.boxRect` etc. The in-flight rect on the node\n // may have been updated by an earlier convergence pass within this batch\n // — reading it would re-introduce the feedback edge this hook exists to\n // eliminate. The committed signal is invariant for the batch.\n markObservedLayoutSignal(node, COMMITTED_RECT_OBSERVED_KEY[committedSignalKey])\n const signals = getLayoutSignals(node)\n const committed = signals[committedSignalKey]()\n return getCommittedRect(committed, node) ?? EMPTY_RECT\n}\n\n// ============================================================================\n// boxRect — layout position (border-box minus padding/border)\n// ============================================================================\n\n/**\n * **DANGEROUS — measurement read on the render path.** Prefer a declarative\n * primitive (`<Box fitWidth>`, `useResponsiveBoxProps`, `useResponsiveValue`,\n * `useOnBoxRectCommitted`) before reaching for this hook.\n *\n * Returns the inner content dimensions for the current component's nearest\n * Box, as of the most recent committed layout. Width and height reflect\n * the space available for children (border-box minus padding and border),\n * like CSS `clientWidth`/`clientHeight`.\n *\n * ```tsx\n * function Header() {\n * const { width } = useBoxRectDangerously()\n * return <Text>{'='.repeat(Math.max(0, width))}</Text>\n * }\n * ```\n *\n * On first render returns `{ x: 0, y: 0, width: 0, height: 0 }`. After the\n * first commit boundary, automatically re-renders with the measured\n * dimensions. This **first-paint zero-rect transition** is the social cost\n * the rename announces — components that branch layout on this hook see a\n * flush-left / collapsed first paint, then re-flow when the real rect\n * commits one event-loop tick later. Visible jank under streaming / dynamic\n * mount / SIGWINCH burst.\n *\n * Use only when:\n * - You need a measurement read in JS control flow (animation, autoscroll\n * thresholds, hit-testing) that **doesn't drive layout-affecting props**.\n * - No declarative primitive covers the case.\n *\n * Deferred semantics — see this file's docstring for the contract and the\n * one-frame-late behavior.\n *\n * Bead: `@km/silvery/responsive-layout-architecture-reframe` (Phase A.1\n * lands this rename; the full Phase A migrates each consumer to a\n * declarative primitive or, where genuinely needed, to a Suspense-friendly\n * `Promise<Rect>` form coordinated via `RectReadBarrier`).\n */\nexport function useBoxRectDangerously(): Rect {\n return useReactiveRect((committed, node) => deriveInnerRect(node, committed), \"boxRectCommitted\")\n}\n\n/**\n * @deprecated Renamed to `useBoxRectDangerously`. The original name read as\n * \"the normal hook for getting your rect\" — exactly the framing the Phase\n * A.1 rename is intended to break. App authors should reach for declarative\n * primitives first; this alias remains for one release cycle and logs a\n * dev-time warning per call site. Will be removed in the next major.\n *\n * Bead: `@km/silvery/responsive-layout-architecture-reframe`.\n */\nexport function useBoxRect(): Rect {\n // Deprecation warning fires once per call site in development. Skipped in\n // production (won't ship) AND test (vitest's fail-on-console policy would\n // trip on every test that exercises the legacy alias — including the very\n // tests that verify backward-compat). Silvery's own internal call sites\n // are migrated to `useBoxRectDangerously` as part of Phase A.1, so test\n // suites don't see the warning either way.\n if (process.env.NODE_ENV !== \"production\" && process.env.NODE_ENV !== \"test\") {\n warnUseBoxRectDeprecation()\n }\n return useReactiveRect((committed, node) => deriveInnerRect(node, committed), \"boxRectCommitted\")\n}\n\n/**\n * Internal dimensions-only variant of the deferred box rect read.\n *\n * This is for framework primitives that build width/height-derived text\n * (Divider, ProgressBar, TextArea wrapping) but do not care where their\n * parent sits on screen. It subscribes to the same committed boxRect signal\n * as `useBoxRect()`, but only re-renders when the derived inner\n * `{width,height}` changes. Scrolling and virtual-window spacer movement\n * often change x/y without changing dimensions; full-rect subscriptions wake\n * these primitives on every such frame and steal scroll budget.\n */\nexport function useBoxSize(): BoxSize {\n const node = useContext(NodeContext)\n const [, forceUpdate] = useReducer((x: number) => x + 1, 0)\n const prevRef = useRef<BoxSize | null>(null)\n\n useLayoutEffect(() => {\n if (!node) return\n\n markObservedLayoutSignal(node, \"boxSize\")\n const signals = getLayoutSignals(node)\n\n const dispose = effect(() => {\n const rect = deriveInnerRect(node, signals.boxRectCommitted())\n const next = rect ? { width: rect.width, height: rect.height } : EMPTY_SIZE\n const prev = prevRef.current\n if (!prev || prev.width !== next.width || prev.height !== next.height) {\n prevRef.current = next\n forceUpdate()\n }\n })\n\n return dispose\n }, [node])\n\n if (!node) return EMPTY_SIZE\n markObservedLayoutSignal(node, \"boxSize\")\n const rect = deriveInnerRect(node, getLayoutSignals(node).boxRectCommitted())\n return rect ? { width: rect.width, height: rect.height } : EMPTY_SIZE\n}\n\nconst useBoxRectWarnedCallSites = new Set<string>()\n\nfunction warnUseBoxRectDeprecation(): void {\n // Dedupe per-call-site so the warning fires once per source location, not\n // once per render. The first stack frame outside this file is the consumer.\n const stack = new Error().stack ?? \"\"\n const lines = stack.split(\"\\n\")\n let consumerFrame = \"\"\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\"\n if (!line.includes(\"useLayout.ts\") && line.trim().startsWith(\"at \")) {\n consumerFrame = line.trim()\n break\n }\n }\n const key = consumerFrame || \"<unknown>\"\n if (useBoxRectWarnedCallSites.has(key)) return\n useBoxRectWarnedCallSites.add(key)\n // eslint-disable-next-line no-console\n console.warn(\n `[silvery] useBoxRect() is deprecated — rename to useBoxRectDangerously(), or migrate to a declarative primitive ` +\n `(<Box fitWidth>, useResponsiveBoxProps, useResponsiveValue, useOnBoxRectCommitted). ` +\n `See @km/silvery/responsive-layout-architecture-reframe. Call site: ${key}`,\n )\n}\n\n// ============================================================================\n// scrollRect — scroll-adjusted position (pre-sticky clamping)\n// ============================================================================\n\n/**\n * Returns the scroll-adjusted position for the current component, as of\n * the most recent committed layout.\n *\n * This is the node's position in scroll coordinates, *before* sticky\n * clamping. For non-sticky nodes it equals `useScreenRect()`. For sticky\n * nodes, the scrollRect reflects where the node would be without sticky\n * adjustment — so it can go off-screen (negative y, etc.) when scrolled\n * past.\n *\n * ```tsx\n * function Card({ id }) {\n * const { y } = useScrollRect()\n * return <Box>Scroll y: {y}</Box>\n * }\n * ```\n *\n * Deferred semantics — see this file's docstring.\n */\nexport function useScrollRect(): Rect {\n return useReactiveRect((committed) => committed, \"scrollRectCommitted\")\n}\n\n// ============================================================================\n// screenRect — actual paint position on the terminal screen\n// ============================================================================\n\n/**\n * Returns the actual paint position on the terminal screen as of the most\n * recent committed layout — the silvery analogue of\n * `getBoundingClientRect()`.\n *\n * For non-sticky nodes this equals `useScrollRect()`. For sticky nodes\n * (`position=\"sticky\"`), it reflects the clamped position where pixels\n * actually land on screen.\n *\n * ```tsx\n * function StickyHeader() {\n * const { y } = useScreenRect()\n * return <Box position=\"sticky\" stickyTop={0}>Header at row {y}</Box>\n * }\n * ```\n *\n * Deferred semantics — see this file's docstring.\n */\nexport function useScreenRect(): Rect {\n return useReactiveRect((committed) => committed, \"screenRectCommitted\")\n}\n\n// ============================================================================\n// In-flight escape hatches — read the live (mid-batch) rect signal\n// ============================================================================\n//\n// The reactive `useBoxRect()` / `useScrollRect()` / `useScreenRect()` hooks\n// return the COMMITTED rect (one frame deferred) — see this file's docstring\n// for the contract. The committed-only contract eliminates render → write →\n// re-measure feedback loops by construction, but it forces components that\n// genuinely need first-paint dimensions to wait one frame.\n//\n// `useBoxRectInFlight()` / `useScrollRectInFlight()` / `useScreenRectInFlight()`\n// subscribe to the IN-FLIGHT signal — the rect as written by the most recent\n// layout pass within the current convergence cycle. The value can change\n// between convergence passes within a single event batch, so a render that\n// reads it AND writes a layout-affecting prop CAN form a feedback edge.\n//\n// **For silvery framework internals only.** Image, useCursor, useGridPosition,\n// and ListView's viewport-tracking path are the real consumers — leaf\n// primitives whose first-paint measurement is critical for scroll, decoration,\n// or absolute-positioning math, and which don't drive layout-affecting props\n// back into the React tree. (Lane snapping, once an in-flight consumer here,\n// now lives in the engine as the `fitWidth` Box prop and doesn't reach for\n// these hooks at all.)\n//\n// **Lint-gated.** App code (silvercode, km-tui, downstream consumers) must\n// not import these hooks — the ESLint rule `silvery/no-in-flight-rect-in-app`\n// blocks imports from outside `vendor/silvery/`. App code that needs\n// first-paint layout decisions must use `useResponsiveBoxProps` /\n// `useResponsiveValue` (declarative, no measurement reads) — the path\n// documented in [The Silvery Way §2](../../docs/guide/the-silvery-way.md).\n//\n// **Why both forms exist.** The deferred form is the safe default; the\n// in-flight form is an explicit escape hatch acknowledging that silvery's\n// own primitives can't always wait one frame for measurement. Naming the\n// escape hatch `*InFlight` makes the cost legible at the call site.\n//\n// See bead `@km/silvery/usebox-rect-deferred-only-breaks-first-paint`.\n\n/**\n * In-flight reactive rect hook (escape hatch): subscribes to the LIVE rect\n * signal — the value as written by the most recent layout pass within the\n * current convergence cycle. Re-renders when the in-flight value advances,\n * which can happen multiple times per event batch as the convergence loop\n * iterates.\n *\n * Use only inside silvery framework internals where first-paint measurement\n * is required and the consumer does not write layout-affecting props\n * derived from the read. App code must use the deferred form\n * (`useBoxRect()` / `useScrollRect()` / `useScreenRect()`) or\n * `useResponsiveBoxProps`/`useResponsiveValue` instead.\n */\nfunction useReactiveRectInFlight(\n getDerivedRect: (raw: Rect | null, node: AgNode) => Rect | null | undefined,\n inFlightSignalKey: InFlightRectSignalKey,\n): Rect {\n const node = useContext(NodeContext)\n const [, forceUpdate] = useReducer((x: number) => x + 1, 0)\n const prevRef = useRef<Rect | null>(null)\n\n useLayoutEffect(() => {\n if (!node) return\n\n markObservedLayoutSignal(node, IN_FLIGHT_RECT_OBSERVED_KEY[inFlightSignalKey])\n const signals = getLayoutSignals(node)\n const rectSignal = signals[inFlightSignalKey]\n\n // effect() subscribes to the IN-FLIGHT signal — re-runs whenever the\n // signal advances, including mid-batch as the convergence loop iterates.\n // This is intentionally permissive vs the committed form; consumers that\n // can't accept first-paint zero-rect (Image, useCursor, useGridPosition)\n // opt in via this hook.\n const dispose = effect(() => {\n const raw = rectSignal()\n const next = getDerivedRect(raw, node) ?? null\n if (!rectEqual(prevRef.current, next)) {\n prevRef.current = next\n forceUpdate()\n }\n })\n\n return dispose\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node])\n\n if (!node) return EMPTY_RECT\n // Synchronous read (called during render): use the in-flight signal\n // directly (NOT `node.boxRect` — that bypasses the reactive subscription\n // edge and would let the render see one value while the effect sees\n // another). The in-flight signal value reflects the most recent layout\n // pass; it may differ between convergence passes within a batch.\n markObservedLayoutSignal(node, IN_FLIGHT_RECT_OBSERVED_KEY[inFlightSignalKey])\n const signals = getLayoutSignals(node)\n const raw = signals[inFlightSignalKey]()\n return getDerivedRect(raw, node) ?? EMPTY_RECT\n}\n\n/**\n * Returns the inner content dimensions of the current Box from the IN-FLIGHT\n * signal — the value as of the most recent layout pass, which may change\n * between convergence passes within an event batch.\n *\n * Silvery framework internals only — app code must use {@link useBoxRect}\n * (deferred) or `useResponsiveBoxProps`/`useResponsiveValue` instead.\n *\n * Unlike {@link useBoxRect} (the deferred form), this hook returns the\n * measured value on the first render after layout — there is no one-frame\n * fallback. The cost is that a render reading this hook AND writing a\n * layout-affecting prop can form a convergence-loop feedback edge; the\n * lint rule `silvery/no-in-flight-rect-in-app` enforces the call-site\n * scope.\n */\nexport function useBoxRectInFlight(): Rect {\n return useReactiveRectInFlight((raw, node) => deriveInnerRect(node, raw), \"boxRect\")\n}\n\n/**\n * Returns the scroll-adjusted position from the IN-FLIGHT signal — the\n * value as of the most recent layout pass, which may change between\n * convergence passes within an event batch.\n *\n * Silvery framework internals only — see {@link useBoxRectInFlight} for\n * the contract and the lint rule that gates app-code use.\n */\nexport function useScrollRectInFlight(): Rect {\n return useReactiveRectInFlight((raw) => raw, \"scrollRect\")\n}\n\n/**\n * Returns the actual paint position from the IN-FLIGHT signal — the value\n * as of the most recent layout pass, which may change between convergence\n * passes within an event batch.\n *\n * Silvery framework internals only — see {@link useBoxRectInFlight} for\n * the contract and the lint rule that gates app-code use.\n */\nexport function useScreenRectInFlight(): Rect {\n return useReactiveRectInFlight((raw) => raw, \"screenRect\")\n}\n\n// ============================================================================\n// Callback observers — fire on commit boundary without triggering re-render\n// ============================================================================\n//\n// The reactive `useBoxRect()` / `useScrollRect()` / `useScreenRect()` hooks\n// re-render the consuming component every time the committed rect advances.\n// For hot paths where the rect change should NOT re-render the consumer\n// (cursor positioning, grid registry, decoration emission), the callback\n// observers below subscribe directly to the committed signal and invoke\n// `cb(rect)` at every commit boundary — no React state churn, no re-render.\n//\n// Restored 2026-05-10 to address the perf regression introduced by removing\n// the callback overload from `useBoxRect()` in silvery `63938779b6`. The\n// previous callback form was `useBoxRect((rect) => …)` overloaded on the\n// reactive hook; that fused two distinct contracts into one signature. The\n// observer hooks below split them: reactive read + commit-boundary observer.\n\n/**\n * Subscribes to the committed rect signal and fires `cb(rect)` at each\n * commit boundary, **without** triggering a re-render of the consumer.\n *\n * Use for hot paths where a rect change drives an imperative side effect\n * (cursor store update, registry write, ANSI emission) and there is no\n * render path that needs to reflect the rect.\n *\n * The callback is invoked synchronously from a commit-boundary effect(),\n * with the derived rect (`getDerivedRect` applied to the committed signal\n * value). It is NOT invoked when the derived rect is null. The caller may\n * close over component state via refs; see `useCursor` / `useGridPosition`\n * for canonical patterns.\n */\nfunction useOnRectCommitted(\n cb: (rect: Rect) => void,\n getDerivedRect: (committed: Rect | null, node: AgNode) => Rect | null | undefined,\n committedSignalKey: CommittedRectSignalKey,\n): void {\n const node = useContext(NodeContext)\n const cbRef = useRef(cb)\n cbRef.current = cb\n\n useLayoutEffect(() => {\n if (!node) return\n\n const signals = getLayoutSignals(node)\n const rectSignal = signals[committedSignalKey]\n let prev: Rect | null = null\n\n const dispose = effect(() => {\n const committed = rectSignal()\n const next = getDerivedRect(committed, node) ?? null\n if (next == null) return\n if (rectEqual(prev, next)) return\n prev = next\n cbRef.current(next)\n })\n\n return dispose\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node])\n}\n\n/**\n * Subscribes to the committed boxRect (inner content) and fires `cb` at\n * each commit boundary without re-rendering. See {@link useBoxRect} for\n * the deferred-rect contract; this is the observer form.\n */\nexport function useOnBoxRectCommitted(cb: (rect: Rect) => void): void {\n useOnRectCommitted(cb, (committed, node) => deriveInnerRect(node, committed), \"boxRectCommitted\")\n}\n\n/**\n * Subscribes to the committed scrollRect and fires `cb` at each commit\n * boundary without re-rendering.\n */\nexport function useOnScrollRectCommitted(cb: (rect: Rect) => void): void {\n useOnRectCommitted(cb, (committed) => committed, \"scrollRectCommitted\")\n}\n\n/**\n * Subscribes to the committed screenRect and fires `cb` at each commit\n * boundary without re-rendering.\n */\nexport function useOnScreenRectCommitted(cb: (rect: Rect) => void): void {\n useOnRectCommitted(cb, (committed) => committed, \"screenRectCommitted\")\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEA,MAAM,aAAmB;CAAE,GAAG;CAAG,GAAG;CAAG,OAAO;CAAG,QAAQ;CAAG;AAC5D,MAAM,aAAsB;CAAE,OAAO;CAAG,QAAQ;CAAG;;;;;;;;;AAenD,SAAS,gBAAgB,MAAc,SAA+C;AACpF,KAAI,CAAC,QAAS,QAAO;CAErB,MAAM,QAAQ,KAAK;AACnB,KAAI,CAAC,SAAS,KAAK,SAAS,eAAgB,QAAO;CAGnD,MAAM,OAAO,MAAM,cAAc,MAAM,YAAY,MAAM,WAAW;CACpE,MAAM,UAAU,MAAM,iBAAiB,MAAM,YAAY,MAAM,WAAW;CAC1E,MAAM,QAAQ,MAAM,eAAe,MAAM,YAAY,MAAM,WAAW;CACtE,MAAM,SAAS,MAAM,gBAAgB,MAAM,YAAY,MAAM,WAAW;CAGxE,IAAI,OAAO;CACX,IAAI,UAAU;CACd,IAAI,QAAQ;CACZ,IAAI,SAAS;AACb,KAAI,MAAM,aAAa;AACrB,SAAO,MAAM,cAAc,QAAQ,IAAI;AACvC,YAAU,MAAM,iBAAiB,QAAQ,IAAI;AAC7C,UAAQ,MAAM,eAAe,QAAQ,IAAI;AACzC,WAAS,MAAM,gBAAgB,QAAQ,IAAI;;AAG7C,QAAO;EACL,GAAG,QAAQ,IAAI,QAAQ;EACvB,GAAG,QAAQ,IAAI,OAAO;EACtB,OAAO,KAAK,IAAI,GAAG,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,OAAO;EACnE,QAAQ,KAAK,IAAI,GAAG,QAAQ,SAAS,OAAO,UAAU,OAAO,QAAQ;EACtE;;AASH,MAAM,8BAAuF;CAC3F,kBAAkB;CAClB,qBAAqB;CACrB,qBAAqB;CACtB;AAED,MAAM,8BAAsF;CAC1F,SAAS;CACT,YAAY;CACZ,YAAY;CACb;;;;;;;;;;;;;AAcD,SAAS,gBACP,kBACA,oBACM;CACN,MAAM,OAAO,WAAW,YAAY;CACpC,MAAM,GAAG,eAAe,YAAY,MAAc,IAAI,GAAG,EAAE;CAC3D,MAAM,UAAU,OAAoB,KAAK;AAEzC,uBAAsB;AACpB,MAAI,CAAC,KAAM;AAEX,2BAAyB,MAAM,4BAA4B,oBAAoB;EAE/E,MAAM,aADU,iBAAiB,KAAK,CACX;AAgB3B,SATgB,aAAa;GAE3B,MAAM,OAAO,iBADK,YAAY,EACW,KAAK,IAAI;AAClD,OAAI,CAAC,UAAU,QAAQ,SAAS,KAAK,EAAE;AACrC,YAAQ,UAAU;AAClB,iBAAa;;IAEf;IAID,CAAC,KAAK,CAAC;AAEV,KAAI,CAAC,KAAM,QAAO;AAMlB,0BAAyB,MAAM,4BAA4B,oBAAoB;AAG/E,QAAO,iBAFS,iBAAiB,KAAK,CACZ,qBAAqB,EACZ,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6C9C,SAAgB,wBAA8B;AAC5C,QAAO,iBAAiB,WAAW,SAAS,gBAAgB,MAAM,UAAU,EAAE,mBAAmB;;;;;;;;;;;AAYnG,SAAgB,aAAmB;AAOjC,KAAI,QAAQ,IAAI,aAAa,gBAAgB,QAAQ,IAAI,aAAa,OACpE,4BAA2B;AAE7B,QAAO,iBAAiB,WAAW,SAAS,gBAAgB,MAAM,UAAU,EAAE,mBAAmB;;;;;;;;;;;;;AAcnG,SAAgB,aAAsB;CACpC,MAAM,OAAO,WAAW,YAAY;CACpC,MAAM,GAAG,eAAe,YAAY,MAAc,IAAI,GAAG,EAAE;CAC3D,MAAM,UAAU,OAAuB,KAAK;AAE5C,uBAAsB;AACpB,MAAI,CAAC,KAAM;AAEX,2BAAyB,MAAM,UAAU;EACzC,MAAM,UAAU,iBAAiB,KAAK;AAYtC,SAVgB,aAAa;GAC3B,MAAM,OAAO,gBAAgB,MAAM,QAAQ,kBAAkB,CAAC;GAC9D,MAAM,OAAO,OAAO;IAAE,OAAO,KAAK;IAAO,QAAQ,KAAK;IAAQ,GAAG;GACjE,MAAM,OAAO,QAAQ;AACrB,OAAI,CAAC,QAAQ,KAAK,UAAU,KAAK,SAAS,KAAK,WAAW,KAAK,QAAQ;AACrE,YAAQ,UAAU;AAClB,iBAAa;;IAEf;IAGD,CAAC,KAAK,CAAC;AAEV,KAAI,CAAC,KAAM,QAAO;AAClB,0BAAyB,MAAM,UAAU;CACzC,MAAM,OAAO,gBAAgB,MAAM,iBAAiB,KAAK,CAAC,kBAAkB,CAAC;AAC7E,QAAO,OAAO;EAAE,OAAO,KAAK;EAAO,QAAQ,KAAK;EAAQ,GAAG;;AAG7D,MAAM,4CAA4B,IAAI,KAAa;AAEnD,SAAS,4BAAkC;CAIzC,MAAM,0BADQ,IAAI,OAAO,EAAC,SAAS,IACf,MAAM,KAAK;CAC/B,IAAI,gBAAgB;AACpB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM,MAAM;AACzB,MAAI,CAAC,KAAK,SAAS,eAAe,IAAI,KAAK,MAAM,CAAC,WAAW,MAAM,EAAE;AACnE,mBAAgB,KAAK,MAAM;AAC3B;;;CAGJ,MAAM,MAAM,iBAAiB;AAC7B,KAAI,0BAA0B,IAAI,IAAI,CAAE;AACxC,2BAA0B,IAAI,IAAI;AAElC,SAAQ,KACN,0QAEwE,MACzE;;;;;;;;;;;;;;;;;;;;;AA0BH,SAAgB,gBAAsB;AACpC,QAAO,iBAAiB,cAAc,WAAW,sBAAsB;;;;;;;;;;;;;;;;;;;;AAyBzE,SAAgB,gBAAsB;AACpC,QAAO,iBAAiB,cAAc,WAAW,sBAAsB;;;;;;;;;;;;;;;AAsDzE,SAAS,wBACP,gBACA,mBACM;CACN,MAAM,OAAO,WAAW,YAAY;CACpC,MAAM,GAAG,eAAe,YAAY,MAAc,IAAI,GAAG,EAAE;CAC3D,MAAM,UAAU,OAAoB,KAAK;AAEzC,uBAAsB;AACpB,MAAI,CAAC,KAAM;AAEX,2BAAyB,MAAM,4BAA4B,mBAAmB;EAE9E,MAAM,aADU,iBAAiB,KAAK,CACX;AAgB3B,SATgB,aAAa;GAE3B,MAAM,OAAO,eADD,YAAY,EACS,KAAK,IAAI;AAC1C,OAAI,CAAC,UAAU,QAAQ,SAAS,KAAK,EAAE;AACrC,YAAQ,UAAU;AAClB,iBAAa;;IAEf;IAID,CAAC,KAAK,CAAC;AAEV,KAAI,CAAC,KAAM,QAAO;AAMlB,0BAAyB,MAAM,4BAA4B,mBAAmB;AAG9E,QAAO,eAFS,iBAAiB,KAAK,CAClB,oBAAoB,EACb,KAAK,IAAI;;;;;;;;;;;;;;;;;AAkBtC,SAAgB,qBAA2B;AACzC,QAAO,yBAAyB,KAAK,SAAS,gBAAgB,MAAM,IAAI,EAAE,UAAU;;;;;;;;;;AAWtF,SAAgB,wBAA8B;AAC5C,QAAO,yBAAyB,QAAQ,KAAK,aAAa;;;;;;;;;;AAW5D,SAAgB,wBAA8B;AAC5C,QAAO,yBAAyB,QAAQ,KAAK,aAAa;;;;;;;;;;;;;;;;AAkC5D,SAAS,mBACP,IACA,gBACA,oBACM;CACN,MAAM,OAAO,WAAW,YAAY;CACpC,MAAM,QAAQ,OAAO,GAAG;AACxB,OAAM,UAAU;AAEhB,uBAAsB;AACpB,MAAI,CAAC,KAAM;EAGX,MAAM,aADU,iBAAiB,KAAK,CACX;EAC3B,IAAI,OAAoB;AAWxB,SATgB,aAAa;GAE3B,MAAM,OAAO,eADK,YAAY,EACS,KAAK,IAAI;AAChD,OAAI,QAAQ,KAAM;AAClB,OAAI,UAAU,MAAM,KAAK,CAAE;AAC3B,UAAO;AACP,SAAM,QAAQ,KAAK;IACnB;IAID,CAAC,KAAK,CAAC;;;;;;;AAQZ,SAAgB,sBAAsB,IAAgC;AACpE,oBAAmB,KAAK,WAAW,SAAS,gBAAgB,MAAM,UAAU,EAAE,mBAAmB;;;;;;AAOnG,SAAgB,yBAAyB,IAAgC;AACvE,oBAAmB,KAAK,cAAc,WAAW,sBAAsB;;;;;;AAOzE,SAAgB,yBAAyB,IAAgC;AACvE,oBAAmB,KAAK,cAAc,WAAW,sBAAsB"}
@@ -1,5 +1,5 @@
1
- import { _ as TextInputOptions, b as WithSpinnerOptions, i as ProgressGenerator, o as SelectOption, y as WithSelectOptions } from "./types-Bx-XZNbE.mjs";
2
- import { r as Spinner } from "./spinner-CLgzJ_QF.mjs";
1
+ import { _ as TextInputOptions, b as WithSpinnerOptions, i as ProgressGenerator, o as SelectOption, y as WithSelectOptions } from "./types-D_E0FbqA.mjs";
2
+ import { r as Spinner } from "./spinner-DN10UfF0.mjs";
3
3
  import { EventEmitter } from "events";
4
4
 
5
5
  //#region packages/ag-react/src/ui/wrappers/with-spinner.d.ts
@@ -230,4 +230,4 @@ interface TextInputInstance {
230
230
  }
231
231
  //#endregion
232
232
  export { waitForEvent as a, wrapGenerator as c, withSelect as i, attachSpinner as l, withTextInput as n, wrapEmitter as o, createSelect as r, withIterableProgress as s, createTextInput as t, withSpinner as u };
233
- //# sourceMappingURL=with-text-input-DG4f7JII.d.mts.map
233
+ //# sourceMappingURL=with-text-input-DLoSCBrm.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"with-text-input-DG4f7JII.d.mts","names":[],"sources":["../packages/ag-react/src/ui/wrappers/with-spinner.ts","../packages/ag-react/src/ui/wrappers/wrap-generator.ts","../packages/ag-react/src/ui/wrappers/wrap-emitter.ts","../packages/ag-react/src/ui/wrappers/with-select.ts","../packages/ag-react/src/ui/wrappers/with-text-input.ts"],"mappings":";;;;;AA6BA;;;;;;;;;;;;;;;;;;;;;;AAAA,iBAAsB,WAAA,GAAA,CACpB,OAAA,EAAS,OAAA,CAAQ,CAAA,WAAY,CAAA,GAAI,OAAA,CAAQ,CAAA,IACzC,IAAA,aAAiB,cAAA,sBACjB,OAAA,GAAS,kBAAA,GACR,OAAA,CAAQ,CAAA;;;;;;AAmDX;;;;;;;iBAAgB,aAAA,GAAA,CACd,OAAA,EAAS,OAAA,CAAQ,CAAA,GACjB,IAAA,UACA,OAAA,GAAS,kBAAA,IACP,OAAA,CAAQ,CAAA,GAAI,OAAA;;;;AA3DhB;;;;;;;;;;;;;;;;;iBCHsB,aAAA,GAAA,CACpB,SAAA,EAAW,iBAAA,CAAkB,CAAA,GAC7B,YAAA,aAAyB,QAAA;EAAY,OAAA;EAAiB,KAAA;AAAA,eACtD,OAAA;EAAW,eAAA;AAAA,IACV,OAAA,CAAQ,CAAA;;;;;;ADsDX;;;;;;iBCeuB,oBAAA,GAAA,CACrB,QAAA,EAAU,QAAA,CAAS,CAAA,IAAK,aAAA,CAAc,CAAA,GACtC,KAAA,UACA,OAAA;EAAW,eAAA;AAAA,IACV,cAAA,CAAe,CAAA;;;;UC/FR,WAAA;EFqBuB;EEnB/B,IAAA;EFoBiB;EElBjB,OAAA,IAAW,IAAA;EFkBkB;EEhB7B,OAAA;EFgBiC;EEdjC,IAAA;EFiBS;EEfT,IAAA;AAAA;;UAIQ,iBAAA;EFQC;EENT,MAAA,EAAQ,MAAA,SAAe,WAAA;EFMM;EEJ7B,WAAA;AAAA;;;;;;;;;;AF0DF;;;;;;;;;;iBEpCgB,WAAA,CAAY,OAAA,EAAS,YAAA,EAAc,MAAA,EAAQ,iBAAA;;;;;;;;;;iBA0DrC,YAAA,CACpB,OAAA,EAAS,YAAA,EACT,SAAA,UACA,IAAA,UACA,OAAA;EACE,UAAA;EACA,OAAA;AAAA,IAED,OAAA;;;;AFrFH;;;;;;;;;;;;;;;;;;;iBGQsB,UAAA,GAAA,CACpB,MAAA,UACA,OAAA,EAAS,YAAA,CAAa,CAAA,KACtB,aAAA,GAAe,iBAAA,GACd,OAAA,CAAQ,CAAA;;;;;;;;;AH2CX;;;;;iBGoHgB,YAAA,CACd,cAAA,GAAgB,iBAAA,OACX,MAAA,UAAgB,OAAA,EAAS,YAAA,CAAa,CAAA,KAAM,SAAA,GAAY,iBAAA,KAAsB,OAAA,CAAQ,CAAA;;;;AH7K7F;;;;;;;;;;;;;;;;;;;;;iBISsB,aAAA,CACpB,MAAA,UACA,OAAA,GAAS,gBAAA,GACR,OAAA;;;;;;;AJ2CH;;;;;;iBIkNgB,eAAA,CAAgB,MAAA,UAAgB,OAAA,GAAS,gBAAA,GAAwB,iBAAA;;UA0EhE,iBAAA;EJxRM;EI0RrB,KAAA;EJ9R4B;EIgS5B,cAAA;EJ/RiB;EIiSjB,MAAA;EJhSA;EIkSA,MAAA,CAAO,IAAA;EJjSP;EImSA,SAAA;EJlSU;EIoSV,MAAA;EJpSqB;EIsSrB,KAAA;;EAEA,gBAAA;AAAA"}
1
+ {"version":3,"file":"with-text-input-DLoSCBrm.d.mts","names":[],"sources":["../packages/ag-react/src/ui/wrappers/with-spinner.ts","../packages/ag-react/src/ui/wrappers/wrap-generator.ts","../packages/ag-react/src/ui/wrappers/wrap-emitter.ts","../packages/ag-react/src/ui/wrappers/with-select.ts","../packages/ag-react/src/ui/wrappers/with-text-input.ts"],"mappings":";;;;;AA6BA;;;;;;;;;;;;;;;;;;;;;;AAAA,iBAAsB,WAAA,GAAA,CACpB,OAAA,EAAS,OAAA,CAAQ,CAAA,WAAY,CAAA,GAAI,OAAA,CAAQ,CAAA,IACzC,IAAA,aAAiB,cAAA,sBACjB,OAAA,GAAS,kBAAA,GACR,OAAA,CAAQ,CAAA;;;;;;AAmDX;;;;;;;iBAAgB,aAAA,GAAA,CACd,OAAA,EAAS,OAAA,CAAQ,CAAA,GACjB,IAAA,UACA,OAAA,GAAS,kBAAA,IACP,OAAA,CAAQ,CAAA,GAAI,OAAA;;;;AA3DhB;;;;;;;;;;;;;;;;;iBCHsB,aAAA,GAAA,CACpB,SAAA,EAAW,iBAAA,CAAkB,CAAA,GAC7B,YAAA,aAAyB,QAAA;EAAY,OAAA;EAAiB,KAAA;AAAA,eACtD,OAAA;EAAW,eAAA;AAAA,IACV,OAAA,CAAQ,CAAA;;;;;;ADsDX;;;;;;iBCeuB,oBAAA,GAAA,CACrB,QAAA,EAAU,QAAA,CAAS,CAAA,IAAK,aAAA,CAAc,CAAA,GACtC,KAAA,UACA,OAAA;EAAW,eAAA;AAAA,IACV,cAAA,CAAe,CAAA;;;;UC/FR,WAAA;EFqBuB;EEnB/B,IAAA;EFoBiB;EElBjB,OAAA,IAAW,IAAA;EFkBkB;EEhB7B,OAAA;EFgBiC;EEdjC,IAAA;EFiBS;EEfT,IAAA;AAAA;;UAIQ,iBAAA;EFQC;EENT,MAAA,EAAQ,MAAA,SAAe,WAAA;EFMM;EEJ7B,WAAA;AAAA;;;;;;;;;;AF0DF;;;;;;;;;;iBEpCgB,WAAA,CAAY,OAAA,EAAS,YAAA,EAAc,MAAA,EAAQ,iBAAA;;;;;;;;;;iBA0DrC,YAAA,CACpB,OAAA,EAAS,YAAA,EACT,SAAA,UACA,IAAA,UACA,OAAA;EACE,UAAA;EACA,OAAA;AAAA,IAED,OAAA;;;;AFrFH;;;;;;;;;;;;;;;;;;;iBGQsB,UAAA,GAAA,CACpB,MAAA,UACA,OAAA,EAAS,YAAA,CAAa,CAAA,KACtB,aAAA,GAAe,iBAAA,GACd,OAAA,CAAQ,CAAA;;;;;;;;;AH2CX;;;;;iBGoHgB,YAAA,CACd,cAAA,GAAgB,iBAAA,OACX,MAAA,UAAgB,OAAA,EAAS,YAAA,CAAa,CAAA,KAAM,SAAA,GAAY,iBAAA,KAAsB,OAAA,CAAQ,CAAA;;;;AH7K7F;;;;;;;;;;;;;;;;;;;;;iBISsB,aAAA,CACpB,MAAA,UACA,OAAA,GAAS,gBAAA,GACR,OAAA;;;;;;;AJ2CH;;;;;;iBIkNgB,eAAA,CAAgB,MAAA,UAAgB,OAAA,GAAS,gBAAA,GAAwB,iBAAA;;UA0EhE,iBAAA;EJxRM;EI0RrB,KAAA;EJ9R4B;EIgS5B,cAAA;EJ/RiB;EIiSjB,MAAA;EJhSA;EIkSA,MAAA,CAAO,IAAA;EJjSP;EImSA,SAAA;EJlSU;EIoSV,MAAA;EJpSqB;EIsSrB,KAAA;;EAEA,gBAAA;AAAA"}