@react-x11/components 0.1.0 → 0.2.1

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 (788) hide show
  1. package/README.md +979 -21
  2. package/dist/ansi/cast.d.ts +48 -0
  3. package/dist/ansi/cast.d.ts.map +1 -0
  4. package/dist/ansi/cast.js +135 -0
  5. package/dist/ansi/cast.js.map +1 -0
  6. package/dist/ansi/index.d.ts +10 -0
  7. package/dist/ansi/index.d.ts.map +1 -0
  8. package/dist/ansi/index.js +27 -0
  9. package/dist/ansi/index.js.map +1 -0
  10. package/dist/ansi/palette.d.ts +79 -0
  11. package/dist/ansi/palette.d.ts.map +1 -0
  12. package/dist/ansi/palette.js +155 -0
  13. package/dist/ansi/palette.js.map +1 -0
  14. package/dist/ansi/parse.d.ts +114 -0
  15. package/dist/ansi/parse.d.ts.map +1 -0
  16. package/dist/ansi/parse.js +687 -0
  17. package/dist/ansi/parse.js.map +1 -0
  18. package/dist/ansi/sgr.d.ts +87 -0
  19. package/dist/ansi/sgr.d.ts.map +1 -0
  20. package/dist/ansi/sgr.js +302 -0
  21. package/dist/ansi/sgr.js.map +1 -0
  22. package/dist/ansi/utf8.d.ts +15 -0
  23. package/dist/ansi/utf8.d.ts.map +1 -0
  24. package/dist/ansi/utf8.js +82 -0
  25. package/dist/ansi/utf8.js.map +1 -0
  26. package/dist/calendar/Calendar.d.ts +136 -0
  27. package/dist/calendar/Calendar.d.ts.map +1 -0
  28. package/dist/calendar/Calendar.js +460 -0
  29. package/dist/calendar/Calendar.js.map +1 -0
  30. package/dist/calendar/DatePicker.d.ts +52 -0
  31. package/dist/calendar/DatePicker.d.ts.map +1 -0
  32. package/dist/calendar/DatePicker.js +257 -0
  33. package/dist/calendar/DatePicker.js.map +1 -0
  34. package/dist/calendar/dates.d.ts +90 -0
  35. package/dist/calendar/dates.d.ts.map +1 -0
  36. package/dist/calendar/dates.js +236 -0
  37. package/dist/calendar/dates.js.map +1 -0
  38. package/dist/calendar/index.d.ts +8 -0
  39. package/dist/calendar/index.d.ts.map +1 -0
  40. package/dist/calendar/index.js +15 -0
  41. package/dist/calendar/index.js.map +1 -0
  42. package/dist/charts/components.d.ts +141 -0
  43. package/dist/charts/components.d.ts.map +1 -0
  44. package/dist/charts/components.js +580 -0
  45. package/dist/charts/components.js.map +1 -0
  46. package/dist/charts/data.d.ts +198 -0
  47. package/dist/charts/data.d.ts.map +1 -0
  48. package/dist/charts/data.js +616 -0
  49. package/dist/charts/data.js.map +1 -0
  50. package/dist/charts/hx.d.ts +21 -0
  51. package/dist/charts/hx.d.ts.map +1 -0
  52. package/dist/charts/hx.js +15 -0
  53. package/dist/charts/hx.js.map +1 -0
  54. package/dist/charts/index.d.ts +27 -0
  55. package/dist/charts/index.d.ts.map +1 -0
  56. package/dist/charts/index.js +38 -0
  57. package/dist/charts/index.js.map +1 -0
  58. package/dist/charts/node.d.ts +96 -0
  59. package/dist/charts/node.d.ts.map +1 -0
  60. package/dist/charts/node.js +720 -0
  61. package/dist/charts/node.js.map +1 -0
  62. package/dist/charts/render.d.ts +153 -0
  63. package/dist/charts/render.d.ts.map +1 -0
  64. package/dist/charts/render.js +762 -0
  65. package/dist/charts/render.js.map +1 -0
  66. package/dist/charts/scale.d.ts +42 -0
  67. package/dist/charts/scale.d.ts.map +1 -0
  68. package/dist/charts/scale.js +173 -0
  69. package/dist/charts/scale.js.map +1 -0
  70. package/dist/charts/spec.d.ts +91 -0
  71. package/dist/charts/spec.d.ts.map +1 -0
  72. package/dist/charts/spec.js +33 -0
  73. package/dist/charts/spec.js.map +1 -0
  74. package/dist/charts/timers.d.ts +6 -0
  75. package/dist/charts/timers.d.ts.map +1 -0
  76. package/dist/charts/timers.js +14 -0
  77. package/dist/charts/timers.js.map +1 -0
  78. package/dist/code/hx.d.ts +24 -0
  79. package/dist/code/hx.d.ts.map +1 -0
  80. package/dist/code/hx.js +25 -0
  81. package/dist/code/hx.js.map +1 -0
  82. package/dist/code/index.d.ts +45 -0
  83. package/dist/code/index.d.ts.map +1 -0
  84. package/dist/code/index.js +93 -0
  85. package/dist/code/index.js.map +1 -0
  86. package/dist/code-editor/completion.d.ts +26 -0
  87. package/dist/code-editor/completion.d.ts.map +1 -0
  88. package/dist/code-editor/completion.js +129 -0
  89. package/dist/code-editor/completion.js.map +1 -0
  90. package/dist/code-editor/doc.d.ts +35 -0
  91. package/dist/code-editor/doc.d.ts.map +1 -0
  92. package/dist/code-editor/doc.js +162 -0
  93. package/dist/code-editor/doc.js.map +1 -0
  94. package/dist/code-editor/hx.d.ts +13 -0
  95. package/dist/code-editor/hx.d.ts.map +1 -0
  96. package/dist/code-editor/hx.js +10 -0
  97. package/dist/code-editor/hx.js.map +1 -0
  98. package/dist/code-editor/index.d.ts +88 -0
  99. package/dist/code-editor/index.d.ts.map +1 -0
  100. package/dist/code-editor/index.js +401 -0
  101. package/dist/code-editor/index.js.map +1 -0
  102. package/dist/code-editor/node.d.ts +343 -0
  103. package/dist/code-editor/node.d.ts.map +1 -0
  104. package/dist/code-editor/node.js +1521 -0
  105. package/dist/code-editor/node.js.map +1 -0
  106. package/dist/code-language/hljs.d.ts +47 -0
  107. package/dist/code-language/hljs.d.ts.map +1 -0
  108. package/dist/code-language/hljs.js +211 -0
  109. package/dist/code-language/hljs.js.map +1 -0
  110. package/dist/code-language/index.d.ts +22 -0
  111. package/dist/code-language/index.d.ts.map +1 -0
  112. package/dist/code-language/index.js +20 -0
  113. package/dist/code-language/index.js.map +1 -0
  114. package/dist/code-language/languages/glsl.d.ts +4 -0
  115. package/dist/code-language/languages/glsl.d.ts.map +1 -0
  116. package/dist/code-language/languages/glsl.js +99 -0
  117. package/dist/code-language/languages/glsl.js.map +1 -0
  118. package/dist/code-language/languages/javascript.d.ts +10 -0
  119. package/dist/code-language/languages/javascript.d.ts.map +1 -0
  120. package/dist/code-language/languages/javascript.js +360 -0
  121. package/dist/code-language/languages/javascript.js.map +1 -0
  122. package/dist/code-language/languages/json.d.ts +4 -0
  123. package/dist/code-language/languages/json.d.ts.map +1 -0
  124. package/dist/code-language/languages/json.js +68 -0
  125. package/dist/code-language/languages/json.js.map +1 -0
  126. package/dist/code-language/languages/shell.d.ts +4 -0
  127. package/dist/code-language/languages/shell.d.ts.map +1 -0
  128. package/dist/code-language/languages/shell.js +189 -0
  129. package/dist/code-language/languages/shell.js.map +1 -0
  130. package/dist/code-language/languages/sql.d.ts +11 -0
  131. package/dist/code-language/languages/sql.d.ts.map +1 -0
  132. package/dist/code-language/languages/sql.js +133 -0
  133. package/dist/code-language/languages/sql.js.map +1 -0
  134. package/dist/code-language/lezer.d.ts +24 -0
  135. package/dist/code-language/lezer.d.ts.map +1 -0
  136. package/dist/code-language/lezer.js +148 -0
  137. package/dist/code-language/lezer.js.map +1 -0
  138. package/dist/code-language/registry.d.ts +19 -0
  139. package/dist/code-language/registry.d.ts.map +1 -0
  140. package/dist/code-language/registry.js +56 -0
  141. package/dist/code-language/registry.js.map +1 -0
  142. package/dist/code-language/runs.d.ts +35 -0
  143. package/dist/code-language/runs.d.ts.map +1 -0
  144. package/dist/code-language/runs.js +88 -0
  145. package/dist/code-language/runs.js.map +1 -0
  146. package/dist/code-language/stream.d.ts +70 -0
  147. package/dist/code-language/stream.d.ts.map +1 -0
  148. package/dist/code-language/stream.js +243 -0
  149. package/dist/code-language/stream.js.map +1 -0
  150. package/dist/code-language/textmate.d.ts +27 -0
  151. package/dist/code-language/textmate.d.ts.map +1 -0
  152. package/dist/code-language/textmate.js +86 -0
  153. package/dist/code-language/textmate.js.map +1 -0
  154. package/dist/code-language/theme.d.ts +26 -0
  155. package/dist/code-language/theme.d.ts.map +1 -0
  156. package/dist/code-language/theme.js +108 -0
  157. package/dist/code-language/theme.js.map +1 -0
  158. package/dist/code-language/timers.d.ts +7 -0
  159. package/dist/code-language/timers.d.ts.map +1 -0
  160. package/dist/code-language/timers.js +22 -0
  161. package/dist/code-language/timers.js.map +1 -0
  162. package/dist/code-language/types.d.ts +173 -0
  163. package/dist/code-language/types.d.ts.map +1 -0
  164. package/dist/code-language/types.js +41 -0
  165. package/dist/code-language/types.js.map +1 -0
  166. package/dist/codeblock/index.d.ts +69 -0
  167. package/dist/codeblock/index.d.ts.map +1 -0
  168. package/dist/codeblock/index.js +85 -0
  169. package/dist/codeblock/index.js.map +1 -0
  170. package/dist/color-picker/ColorField.d.ts +39 -0
  171. package/dist/color-picker/ColorField.d.ts.map +1 -0
  172. package/dist/color-picker/ColorField.js +239 -0
  173. package/dist/color-picker/ColorField.js.map +1 -0
  174. package/dist/color-picker/ColorPicker.d.ts +109 -0
  175. package/dist/color-picker/ColorPicker.d.ts.map +1 -0
  176. package/dist/color-picker/ColorPicker.js +757 -0
  177. package/dist/color-picker/ColorPicker.js.map +1 -0
  178. package/dist/color-picker/color.d.ts +105 -0
  179. package/dist/color-picker/color.d.ts.map +1 -0
  180. package/dist/color-picker/color.js +313 -0
  181. package/dist/color-picker/color.js.map +1 -0
  182. package/dist/color-picker/index.d.ts +8 -0
  183. package/dist/color-picker/index.d.ts.map +1 -0
  184. package/dist/color-picker/index.js +19 -0
  185. package/dist/color-picker/index.js.map +1 -0
  186. package/dist/desktop-calendar/eds.d.ts +102 -0
  187. package/dist/desktop-calendar/eds.d.ts.map +1 -0
  188. package/dist/desktop-calendar/eds.js +356 -0
  189. package/dist/desktop-calendar/eds.js.map +1 -0
  190. package/dist/desktop-calendar/ical.d.ts +63 -0
  191. package/dist/desktop-calendar/ical.d.ts.map +1 -0
  192. package/dist/desktop-calendar/ical.js +57 -0
  193. package/dist/desktop-calendar/ical.js.map +1 -0
  194. package/dist/desktop-calendar/index.d.ts +72 -0
  195. package/dist/desktop-calendar/index.d.ts.map +1 -0
  196. package/dist/desktop-calendar/index.js +213 -0
  197. package/dist/desktop-calendar/index.js.map +1 -0
  198. package/dist/embed/client.d.ts +121 -0
  199. package/dist/embed/client.d.ts.map +1 -0
  200. package/dist/embed/client.js +203 -0
  201. package/dist/embed/client.js.map +1 -0
  202. package/dist/embed/host.d.ts +96 -0
  203. package/dist/embed/host.d.ts.map +1 -0
  204. package/dist/embed/host.js +266 -0
  205. package/dist/embed/host.js.map +1 -0
  206. package/dist/embed/index.d.ts +5 -0
  207. package/dist/embed/index.d.ts.map +1 -0
  208. package/dist/embed/index.js +13 -0
  209. package/dist/embed/index.js.map +1 -0
  210. package/dist/embed/timers.d.ts +6 -0
  211. package/dist/embed/timers.d.ts.map +1 -0
  212. package/dist/embed/timers.js +16 -0
  213. package/dist/embed/timers.js.map +1 -0
  214. package/dist/flow/draw.d.ts +45 -0
  215. package/dist/flow/draw.d.ts.map +1 -0
  216. package/dist/flow/draw.js +295 -0
  217. package/dist/flow/draw.js.map +1 -0
  218. package/dist/flow/index.d.ts +64 -0
  219. package/dist/flow/index.d.ts.map +1 -0
  220. package/dist/flow/index.js +306 -0
  221. package/dist/flow/index.js.map +1 -0
  222. package/dist/flow/model.d.ts +158 -0
  223. package/dist/flow/model.d.ts.map +1 -0
  224. package/dist/flow/model.js +566 -0
  225. package/dist/flow/model.js.map +1 -0
  226. package/dist/flow/node.d.ts +429 -0
  227. package/dist/flow/node.d.ts.map +1 -0
  228. package/dist/flow/node.js +3025 -0
  229. package/dist/flow/node.js.map +1 -0
  230. package/dist/flow/paths.d.ts +43 -0
  231. package/dist/flow/paths.d.ts.map +1 -0
  232. package/dist/flow/paths.js +327 -0
  233. package/dist/flow/paths.js.map +1 -0
  234. package/dist/flow/types.d.ts +561 -0
  235. package/dist/flow/types.d.ts.map +1 -0
  236. package/dist/flow/types.js +2 -0
  237. package/dist/flow/types.js.map +1 -0
  238. package/dist/formula/hx.d.ts +24 -0
  239. package/dist/formula/hx.d.ts.map +1 -0
  240. package/dist/formula/hx.js +25 -0
  241. package/dist/formula/hx.js.map +1 -0
  242. package/dist/formula/index.d.ts +74 -0
  243. package/dist/formula/index.d.ts.map +1 -0
  244. package/dist/formula/index.js +155 -0
  245. package/dist/formula/index.js.map +1 -0
  246. package/dist/formula/katex.d.ts +78 -0
  247. package/dist/formula/katex.d.ts.map +1 -0
  248. package/dist/formula/katex.js +130 -0
  249. package/dist/formula/katex.js.map +1 -0
  250. package/dist/formula/layout.d.ts +103 -0
  251. package/dist/formula/layout.d.ts.map +1 -0
  252. package/dist/formula/layout.js +716 -0
  253. package/dist/formula/layout.js.map +1 -0
  254. package/dist/formula/node.d.ts +50 -0
  255. package/dist/formula/node.d.ts.map +1 -0
  256. package/dist/formula/node.js +351 -0
  257. package/dist/formula/node.js.map +1 -0
  258. package/dist/html/controls.d.ts +48 -0
  259. package/dist/html/controls.d.ts.map +1 -0
  260. package/dist/html/controls.js +195 -0
  261. package/dist/html/controls.js.map +1 -0
  262. package/dist/html/css/cascade.d.ts +51 -0
  263. package/dist/html/css/cascade.d.ts.map +1 -0
  264. package/dist/html/css/cascade.js +552 -0
  265. package/dist/html/css/cascade.js.map +1 -0
  266. package/dist/html/css/parse.d.ts +74 -0
  267. package/dist/html/css/parse.d.ts.map +1 -0
  268. package/dist/html/css/parse.js +464 -0
  269. package/dist/html/css/parse.js.map +1 -0
  270. package/dist/html/css/style.d.ts +142 -0
  271. package/dist/html/css/style.d.ts.map +1 -0
  272. package/dist/html/css/style.js +1145 -0
  273. package/dist/html/css/style.js.map +1 -0
  274. package/dist/html/css/ua.d.ts +5 -0
  275. package/dist/html/css/ua.d.ts.map +1 -0
  276. package/dist/html/css/ua.js +171 -0
  277. package/dist/html/css/ua.js.map +1 -0
  278. package/dist/html/css/values.d.ts +78 -0
  279. package/dist/html/css/values.d.ts.map +1 -0
  280. package/dist/html/css/values.js +330 -0
  281. package/dist/html/css/values.js.map +1 -0
  282. package/dist/html/dom.d.ts +112 -0
  283. package/dist/html/dom.d.ts.map +1 -0
  284. package/dist/html/dom.js +374 -0
  285. package/dist/html/dom.js.map +1 -0
  286. package/dist/html/hx.d.ts +24 -0
  287. package/dist/html/hx.d.ts.map +1 -0
  288. package/dist/html/hx.js +29 -0
  289. package/dist/html/hx.js.map +1 -0
  290. package/dist/html/index.d.ts +137 -0
  291. package/dist/html/index.d.ts.map +1 -0
  292. package/dist/html/index.js +339 -0
  293. package/dist/html/index.js.map +1 -0
  294. package/dist/html/layout/block.d.ts +58 -0
  295. package/dist/html/layout/block.d.ts.map +1 -0
  296. package/dist/html/layout/block.js +724 -0
  297. package/dist/html/layout/block.js.map +1 -0
  298. package/dist/html/layout/boxes.d.ts +261 -0
  299. package/dist/html/layout/boxes.d.ts.map +1 -0
  300. package/dist/html/layout/boxes.js +725 -0
  301. package/dist/html/layout/boxes.js.map +1 -0
  302. package/dist/html/layout/flex.d.ts +16 -0
  303. package/dist/html/layout/flex.d.ts.map +1 -0
  304. package/dist/html/layout/flex.js +242 -0
  305. package/dist/html/layout/flex.js.map +1 -0
  306. package/dist/html/layout/floats.d.ts +50 -0
  307. package/dist/html/layout/floats.d.ts.map +1 -0
  308. package/dist/html/layout/floats.js +110 -0
  309. package/dist/html/layout/floats.js.map +1 -0
  310. package/dist/html/layout/inline.d.ts +44 -0
  311. package/dist/html/layout/inline.d.ts.map +1 -0
  312. package/dist/html/layout/inline.js +700 -0
  313. package/dist/html/layout/inline.js.map +1 -0
  314. package/dist/html/layout/table.d.ts +5 -0
  315. package/dist/html/layout/table.d.ts.map +1 -0
  316. package/dist/html/layout/table.js +340 -0
  317. package/dist/html/layout/table.js.map +1 -0
  318. package/dist/html/node.d.ts +149 -0
  319. package/dist/html/node.d.ts.map +1 -0
  320. package/dist/html/node.js +861 -0
  321. package/dist/html/node.js.map +1 -0
  322. package/dist/html/paint.d.ts +48 -0
  323. package/dist/html/paint.d.ts.map +1 -0
  324. package/dist/html/paint.js +495 -0
  325. package/dist/html/paint.js.map +1 -0
  326. package/dist/html/resources.d.ts +48 -0
  327. package/dist/html/resources.d.ts.map +1 -0
  328. package/dist/html/resources.js +156 -0
  329. package/dist/html/resources.js.map +1 -0
  330. package/dist/index.d.ts +48 -0
  331. package/dist/index.d.ts.map +1 -0
  332. package/dist/index.js +92 -0
  333. package/dist/index.js.map +1 -0
  334. package/dist/internal/heights.d.ts +88 -0
  335. package/dist/internal/heights.d.ts.map +1 -0
  336. package/dist/internal/heights.js +203 -0
  337. package/dist/internal/heights.js.map +1 -0
  338. package/dist/internal/hx.d.ts +24 -0
  339. package/dist/internal/hx.d.ts.map +1 -0
  340. package/dist/internal/hx.js +27 -0
  341. package/dist/internal/hx.js.map +1 -0
  342. package/dist/internal/scroll.d.ts +62 -0
  343. package/dist/internal/scroll.d.ts.map +1 -0
  344. package/dist/internal/scroll.js +224 -0
  345. package/dist/internal/scroll.js.map +1 -0
  346. package/dist/internal/text.d.ts +6 -0
  347. package/dist/internal/text.d.ts.map +1 -0
  348. package/dist/internal/text.js +44 -0
  349. package/dist/internal/text.js.map +1 -0
  350. package/dist/internal/timers.d.ts +8 -0
  351. package/dist/internal/timers.d.ts.map +1 -0
  352. package/dist/internal/timers.js +22 -0
  353. package/dist/internal/timers.js.map +1 -0
  354. package/dist/internal/widget.d.ts +40 -0
  355. package/dist/internal/widget.d.ts.map +1 -0
  356. package/dist/internal/widget.js +44 -0
  357. package/dist/internal/widget.js.map +1 -0
  358. package/dist/markdown/ast.d.ts +126 -0
  359. package/dist/markdown/ast.d.ts.map +1 -0
  360. package/dist/markdown/ast.js +8 -0
  361. package/dist/markdown/ast.js.map +1 -0
  362. package/dist/markdown/hx.d.ts +24 -0
  363. package/dist/markdown/hx.d.ts.map +1 -0
  364. package/dist/markdown/hx.js +25 -0
  365. package/dist/markdown/hx.js.map +1 -0
  366. package/dist/markdown/index.d.ts +90 -0
  367. package/dist/markdown/index.d.ts.map +1 -0
  368. package/dist/markdown/index.js +413 -0
  369. package/dist/markdown/index.js.map +1 -0
  370. package/dist/markdown/parse.d.ts +8 -0
  371. package/dist/markdown/parse.d.ts.map +1 -0
  372. package/dist/markdown/parse.js +911 -0
  373. package/dist/markdown/parse.js.map +1 -0
  374. package/dist/markdown/spans.d.ts +20 -0
  375. package/dist/markdown/spans.d.ts.map +1 -0
  376. package/dist/markdown/spans.js +96 -0
  377. package/dist/markdown/spans.js.map +1 -0
  378. package/dist/media-player/backends.d.ts +64 -0
  379. package/dist/media-player/backends.d.ts.map +1 -0
  380. package/dist/media-player/backends.js +110 -0
  381. package/dist/media-player/backends.js.map +1 -0
  382. package/dist/media-player/control.d.ts +40 -0
  383. package/dist/media-player/control.d.ts.map +1 -0
  384. package/dist/media-player/control.js +44 -0
  385. package/dist/media-player/control.js.map +1 -0
  386. package/dist/media-player/hx.d.ts +24 -0
  387. package/dist/media-player/hx.d.ts.map +1 -0
  388. package/dist/media-player/hx.js +25 -0
  389. package/dist/media-player/hx.js.map +1 -0
  390. package/dist/media-player/index.d.ts +107 -0
  391. package/dist/media-player/index.d.ts.map +1 -0
  392. package/dist/media-player/index.js +219 -0
  393. package/dist/media-player/index.js.map +1 -0
  394. package/dist/media-player/mpv.d.ts +4 -0
  395. package/dist/media-player/mpv.d.ts.map +1 -0
  396. package/dist/media-player/mpv.js +120 -0
  397. package/dist/media-player/mpv.js.map +1 -0
  398. package/dist/media-player/vlc.d.ts +8 -0
  399. package/dist/media-player/vlc.d.ts.map +1 -0
  400. package/dist/media-player/vlc.js +83 -0
  401. package/dist/media-player/vlc.js.map +1 -0
  402. package/dist/richtext/index.d.ts +19 -0
  403. package/dist/richtext/index.d.ts.map +1 -0
  404. package/dist/richtext/index.js +4 -0
  405. package/dist/richtext/index.js.map +1 -0
  406. package/dist/richtext/links.d.ts +12 -0
  407. package/dist/richtext/links.d.ts.map +1 -0
  408. package/dist/richtext/links.js +64 -0
  409. package/dist/richtext/links.js.map +1 -0
  410. package/dist/richtext/menu.d.ts +11 -0
  411. package/dist/richtext/menu.d.ts.map +1 -0
  412. package/dist/richtext/menu.js +43 -0
  413. package/dist/richtext/menu.js.map +1 -0
  414. package/dist/richtext/node.d.ts +151 -0
  415. package/dist/richtext/node.d.ts.map +1 -0
  416. package/dist/richtext/node.js +255 -0
  417. package/dist/richtext/node.js.map +1 -0
  418. package/dist/richtext/runs.d.ts +92 -0
  419. package/dist/richtext/runs.d.ts.map +1 -0
  420. package/dist/richtext/runs.js +158 -0
  421. package/dist/richtext/runs.js.map +1 -0
  422. package/dist/table/hx.d.ts +24 -0
  423. package/dist/table/hx.d.ts.map +1 -0
  424. package/dist/table/hx.js +25 -0
  425. package/dist/table/hx.js.map +1 -0
  426. package/dist/table/index.d.ts +169 -0
  427. package/dist/table/index.d.ts.map +1 -0
  428. package/dist/table/index.js +890 -0
  429. package/dist/table/index.js.map +1 -0
  430. package/dist/table/rows.d.ts +136 -0
  431. package/dist/table/rows.d.ts.map +1 -0
  432. package/dist/table/rows.js +146 -0
  433. package/dist/table/rows.js.map +1 -0
  434. package/dist/terminal/backends.d.ts +105 -0
  435. package/dist/terminal/backends.d.ts.map +1 -0
  436. package/dist/terminal/backends.js +185 -0
  437. package/dist/terminal/backends.js.map +1 -0
  438. package/dist/terminal/hx.d.ts +24 -0
  439. package/dist/terminal/hx.d.ts.map +1 -0
  440. package/dist/terminal/hx.js +25 -0
  441. package/dist/terminal/hx.js.map +1 -0
  442. package/dist/terminal/index.d.ts +160 -0
  443. package/dist/terminal/index.d.ts.map +1 -0
  444. package/dist/terminal/index.js +344 -0
  445. package/dist/terminal/index.js.map +1 -0
  446. package/dist/terminal/title.d.ts +24 -0
  447. package/dist/terminal/title.d.ts.map +1 -0
  448. package/dist/terminal/title.js +129 -0
  449. package/dist/terminal/title.js.map +1 -0
  450. package/dist/terminal/vt/colors.d.ts +63 -0
  451. package/dist/terminal/vt/colors.d.ts.map +1 -0
  452. package/dist/terminal/vt/colors.js +203 -0
  453. package/dist/terminal/vt/colors.js.map +1 -0
  454. package/dist/terminal/vt/diff.d.ts +117 -0
  455. package/dist/terminal/vt/diff.d.ts.map +1 -0
  456. package/dist/terminal/vt/diff.js +358 -0
  457. package/dist/terminal/vt/diff.js.map +1 -0
  458. package/dist/terminal/vt/fonts.d.ts +92 -0
  459. package/dist/terminal/vt/fonts.d.ts.map +1 -0
  460. package/dist/terminal/vt/fonts.js +178 -0
  461. package/dist/terminal/vt/fonts.js.map +1 -0
  462. package/dist/terminal/vt/index.d.ts +78 -0
  463. package/dist/terminal/vt/index.d.ts.map +1 -0
  464. package/dist/terminal/vt/index.js +312 -0
  465. package/dist/terminal/vt/index.js.map +1 -0
  466. package/dist/terminal/vt/keys.d.ts +74 -0
  467. package/dist/terminal/vt/keys.d.ts.map +1 -0
  468. package/dist/terminal/vt/keys.js +309 -0
  469. package/dist/terminal/vt/keys.js.map +1 -0
  470. package/dist/terminal/vt/mouse.d.ts +44 -0
  471. package/dist/terminal/vt/mouse.d.ts.map +1 -0
  472. package/dist/terminal/vt/mouse.js +106 -0
  473. package/dist/terminal/vt/mouse.js.map +1 -0
  474. package/dist/terminal/vt/node.d.ts +246 -0
  475. package/dist/terminal/vt/node.d.ts.map +1 -0
  476. package/dist/terminal/vt/node.js +1068 -0
  477. package/dist/terminal/vt/node.js.map +1 -0
  478. package/dist/terminal/vt/pty.d.ts +81 -0
  479. package/dist/terminal/vt/pty.d.ts.map +1 -0
  480. package/dist/terminal/vt/pty.js +201 -0
  481. package/dist/terminal/vt/pty.js.map +1 -0
  482. package/dist/terminal/vt/renderer.d.ts +179 -0
  483. package/dist/terminal/vt/renderer.d.ts.map +1 -0
  484. package/dist/terminal/vt/renderer.js +357 -0
  485. package/dist/terminal/vt/renderer.js.map +1 -0
  486. package/dist/terminal/vt/timers.d.ts +6 -0
  487. package/dist/terminal/vt/timers.d.ts.map +1 -0
  488. package/dist/terminal/vt/timers.js +16 -0
  489. package/dist/terminal/vt/timers.js.map +1 -0
  490. package/dist/terminal/vt/xterm.d.ts +142 -0
  491. package/dist/terminal/vt/xterm.d.ts.map +1 -0
  492. package/dist/terminal/vt/xterm.js +32 -0
  493. package/dist/terminal/vt/xterm.js.map +1 -0
  494. package/dist/terminal-output/hx.d.ts +24 -0
  495. package/dist/terminal-output/hx.d.ts.map +1 -0
  496. package/dist/terminal-output/hx.js +25 -0
  497. package/dist/terminal-output/hx.js.map +1 -0
  498. package/dist/terminal-output/index.d.ts +92 -0
  499. package/dist/terminal-output/index.d.ts.map +1 -0
  500. package/dist/terminal-output/index.js +179 -0
  501. package/dist/terminal-output/index.js.map +1 -0
  502. package/dist/terminal-output/runs.d.ts +27 -0
  503. package/dist/terminal-output/runs.d.ts.map +1 -0
  504. package/dist/terminal-output/runs.js +66 -0
  505. package/dist/terminal-output/runs.js.map +1 -0
  506. package/dist/three/canvas.d.ts +46 -0
  507. package/dist/three/canvas.d.ts.map +1 -0
  508. package/dist/three/canvas.js +305 -0
  509. package/dist/three/canvas.js.map +1 -0
  510. package/dist/three/events.d.ts +64 -0
  511. package/dist/three/events.d.ts.map +1 -0
  512. package/dist/three/events.js +146 -0
  513. package/dist/three/events.js.map +1 -0
  514. package/dist/three/geometries.d.ts +89 -0
  515. package/dist/three/geometries.d.ts.map +1 -0
  516. package/dist/three/geometries.js +345 -0
  517. package/dist/three/geometries.js.map +1 -0
  518. package/dist/three/globals.d.ts +7 -0
  519. package/dist/three/globals.d.ts.map +1 -0
  520. package/dist/three/globals.js +20 -0
  521. package/dist/three/globals.js.map +1 -0
  522. package/dist/three/hx.d.ts +9 -0
  523. package/dist/three/hx.d.ts.map +1 -0
  524. package/dist/three/hx.js +10 -0
  525. package/dist/three/hx.js.map +1 -0
  526. package/dist/three/index.d.ts +22 -0
  527. package/dist/three/index.d.ts.map +1 -0
  528. package/dist/three/index.js +24 -0
  529. package/dist/three/index.js.map +1 -0
  530. package/dist/three/jsx-dev-runtime.d.ts +19 -0
  531. package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
  532. package/dist/three/jsx-dev-runtime.js +2 -0
  533. package/dist/three/jsx-dev-runtime.js.map +1 -0
  534. package/dist/three/jsx-runtime.d.ts +19 -0
  535. package/dist/three/jsx-runtime.d.ts.map +1 -0
  536. package/dist/three/jsx-runtime.js +2 -0
  537. package/dist/three/jsx-runtime.js.map +1 -0
  538. package/dist/three/jsx.d.ts +198 -0
  539. package/dist/three/jsx.d.ts.map +1 -0
  540. package/dist/three/jsx.js +2 -0
  541. package/dist/three/jsx.js.map +1 -0
  542. package/dist/three/materials.d.ts +125 -0
  543. package/dist/three/materials.d.ts.map +1 -0
  544. package/dist/three/materials.js +229 -0
  545. package/dist/three/materials.js.map +1 -0
  546. package/dist/three/math.d.ts +146 -0
  547. package/dist/three/math.d.ts.map +1 -0
  548. package/dist/three/math.js +464 -0
  549. package/dist/three/math.js.map +1 -0
  550. package/dist/three/objects.d.ts +185 -0
  551. package/dist/three/objects.d.ts.map +1 -0
  552. package/dist/three/objects.js +309 -0
  553. package/dist/three/objects.js.map +1 -0
  554. package/dist/three/passes.d.ts +54 -0
  555. package/dist/three/passes.d.ts.map +1 -0
  556. package/dist/three/passes.js +78 -0
  557. package/dist/three/passes.js.map +1 -0
  558. package/dist/three/postprocess.d.ts +85 -0
  559. package/dist/three/postprocess.d.ts.map +1 -0
  560. package/dist/three/postprocess.js +503 -0
  561. package/dist/three/postprocess.js.map +1 -0
  562. package/dist/three/raycast.d.ts +24 -0
  563. package/dist/three/raycast.d.ts.map +1 -0
  564. package/dist/three/raycast.js +138 -0
  565. package/dist/three/raycast.js.map +1 -0
  566. package/dist/three/reconciler.d.ts +48 -0
  567. package/dist/three/reconciler.d.ts.map +1 -0
  568. package/dist/three/reconciler.js +416 -0
  569. package/dist/three/reconciler.js.map +1 -0
  570. package/dist/three/renderer-direct.d.ts +102 -0
  571. package/dist/three/renderer-direct.d.ts.map +1 -0
  572. package/dist/three/renderer-direct.js +782 -0
  573. package/dist/three/renderer-direct.js.map +1 -0
  574. package/dist/three/renderer-indirect.d.ts +68 -0
  575. package/dist/three/renderer-indirect.d.ts.map +1 -0
  576. package/dist/three/renderer-indirect.js +438 -0
  577. package/dist/three/renderer-indirect.js.map +1 -0
  578. package/dist/three/store.d.ts +81 -0
  579. package/dist/three/store.d.ts.map +1 -0
  580. package/dist/three/store.js +110 -0
  581. package/dist/three/store.js.map +1 -0
  582. package/dist/timeline/hx.d.ts +18 -0
  583. package/dist/timeline/hx.d.ts.map +1 -0
  584. package/dist/timeline/hx.js +10 -0
  585. package/dist/timeline/hx.js.map +1 -0
  586. package/dist/timeline/index.d.ts +152 -0
  587. package/dist/timeline/index.d.ts.map +1 -0
  588. package/dist/timeline/index.js +383 -0
  589. package/dist/timeline/index.js.map +1 -0
  590. package/dist/tray-host/hx.d.ts +24 -0
  591. package/dist/tray-host/hx.d.ts.map +1 -0
  592. package/dist/tray-host/hx.js +25 -0
  593. package/dist/tray-host/hx.js.map +1 -0
  594. package/dist/tray-host/index.d.ts +110 -0
  595. package/dist/tray-host/index.d.ts.map +1 -0
  596. package/dist/tray-host/index.js +191 -0
  597. package/dist/tray-host/index.js.map +1 -0
  598. package/dist/tray-host/manager.d.ts +137 -0
  599. package/dist/tray-host/manager.d.ts.map +1 -0
  600. package/dist/tray-host/manager.js +462 -0
  601. package/dist/tray-host/manager.js.map +1 -0
  602. package/dist/tray-host/notify.d.ts +22 -0
  603. package/dist/tray-host/notify.d.ts.map +1 -0
  604. package/dist/tray-host/notify.js +74 -0
  605. package/dist/tray-host/notify.js.map +1 -0
  606. package/dist/tray-host/protocol.d.ts +106 -0
  607. package/dist/tray-host/protocol.d.ts.map +1 -0
  608. package/dist/tray-host/protocol.js +191 -0
  609. package/dist/tray-host/protocol.js.map +1 -0
  610. package/dist/tree/hx.d.ts +24 -0
  611. package/dist/tree/hx.d.ts.map +1 -0
  612. package/dist/tree/hx.js +25 -0
  613. package/dist/tree/hx.js.map +1 -0
  614. package/dist/tree/index.d.ts +221 -0
  615. package/dist/tree/index.d.ts.map +1 -0
  616. package/dist/tree/index.js +751 -0
  617. package/dist/tree/index.js.map +1 -0
  618. package/dist/tree/internal.d.ts +18 -0
  619. package/dist/tree/internal.d.ts.map +1 -0
  620. package/dist/tree/internal.js +66 -0
  621. package/dist/tree/internal.js.map +1 -0
  622. package/dist/tree/rows.d.ts +177 -0
  623. package/dist/tree/rows.d.ts.map +1 -0
  624. package/dist/tree/rows.js +179 -0
  625. package/dist/tree/rows.js.map +1 -0
  626. package/package.json +166 -12
  627. package/src/ansi/cast.ts +159 -0
  628. package/src/ansi/index.ts +53 -0
  629. package/src/ansi/palette.ts +226 -0
  630. package/src/ansi/parse.ts +780 -0
  631. package/src/ansi/sgr.ts +380 -0
  632. package/src/ansi/utf8.ts +84 -0
  633. package/src/calendar/Calendar.ts +744 -0
  634. package/src/calendar/DatePicker.ts +368 -0
  635. package/src/calendar/dates.ts +307 -0
  636. package/src/calendar/index.ts +51 -0
  637. package/src/charts/components.ts +864 -0
  638. package/src/charts/data.ts +776 -0
  639. package/src/charts/hx.ts +39 -0
  640. package/src/charts/index.ts +99 -0
  641. package/src/charts/node.ts +932 -0
  642. package/src/charts/render.ts +982 -0
  643. package/src/charts/scale.ts +214 -0
  644. package/src/charts/spec.ts +122 -0
  645. package/src/charts/timers.ts +24 -0
  646. package/src/code/hx.ts +51 -0
  647. package/src/code/index.ts +174 -0
  648. package/src/code-editor/completion.ts +161 -0
  649. package/src/code-editor/doc.ts +198 -0
  650. package/src/code-editor/hx.ts +26 -0
  651. package/src/code-editor/index.ts +615 -0
  652. package/src/code-editor/node.ts +1926 -0
  653. package/src/code-language/hljs.ts +302 -0
  654. package/src/code-language/index.ts +51 -0
  655. package/src/code-language/languages/glsl.ts +120 -0
  656. package/src/code-language/languages/javascript.ts +419 -0
  657. package/src/code-language/languages/json.ts +72 -0
  658. package/src/code-language/languages/shell.ts +221 -0
  659. package/src/code-language/languages/sql.ts +165 -0
  660. package/src/code-language/lezer.ts +190 -0
  661. package/src/code-language/registry.ts +66 -0
  662. package/src/code-language/runs.ts +128 -0
  663. package/src/code-language/stream.ts +306 -0
  664. package/src/code-language/textmate.ts +134 -0
  665. package/src/code-language/theme.ts +124 -0
  666. package/src/code-language/timers.ts +36 -0
  667. package/src/code-language/types.ts +252 -0
  668. package/src/codeblock/index.ts +146 -0
  669. package/src/color-picker/ColorField.ts +333 -0
  670. package/src/color-picker/ColorPicker.ts +1069 -0
  671. package/src/color-picker/color.ts +399 -0
  672. package/src/color-picker/index.ts +50 -0
  673. package/src/desktop-calendar/eds.ts +484 -0
  674. package/src/desktop-calendar/ical.ts +119 -0
  675. package/src/desktop-calendar/index.ts +287 -0
  676. package/src/embed/client.ts +311 -0
  677. package/src/embed/host.ts +432 -0
  678. package/src/embed/index.ts +33 -0
  679. package/src/embed/timers.ts +32 -0
  680. package/src/flow/draw.ts +418 -0
  681. package/src/flow/index.ts +473 -0
  682. package/src/flow/model.ts +687 -0
  683. package/src/flow/node.ts +3694 -0
  684. package/src/flow/paths.ts +403 -0
  685. package/src/flow/types.ts +634 -0
  686. package/src/formula/hx.ts +51 -0
  687. package/src/formula/index.ts +243 -0
  688. package/src/formula/katex.ts +209 -0
  689. package/src/formula/layout.ts +876 -0
  690. package/src/formula/node.ts +467 -0
  691. package/src/html/controls.ts +244 -0
  692. package/src/html/css/cascade.ts +606 -0
  693. package/src/html/css/parse.ts +500 -0
  694. package/src/html/css/style.ts +1371 -0
  695. package/src/html/css/ua.ts +174 -0
  696. package/src/html/css/values.ts +358 -0
  697. package/src/html/dom.ts +410 -0
  698. package/src/html/hx.ts +55 -0
  699. package/src/html/index.ts +545 -0
  700. package/src/html/layout/block.ts +876 -0
  701. package/src/html/layout/boxes.ts +981 -0
  702. package/src/html/layout/flex.ts +297 -0
  703. package/src/html/layout/floats.ts +125 -0
  704. package/src/html/layout/inline.ts +870 -0
  705. package/src/html/layout/table.ts +380 -0
  706. package/src/html/node.ts +967 -0
  707. package/src/html/paint.ts +605 -0
  708. package/src/html/resources.ts +214 -0
  709. package/src/index.ts +638 -0
  710. package/src/internal/heights.ts +222 -0
  711. package/src/internal/hx.ts +53 -0
  712. package/src/internal/scroll.ts +288 -0
  713. package/src/internal/text.ts +44 -0
  714. package/src/internal/timers.ts +44 -0
  715. package/src/internal/widget.ts +92 -0
  716. package/src/markdown/ast.ts +163 -0
  717. package/src/markdown/hx.ts +51 -0
  718. package/src/markdown/index.ts +686 -0
  719. package/src/markdown/parse.ts +1037 -0
  720. package/src/markdown/spans.ts +143 -0
  721. package/src/media-player/backends.ts +155 -0
  722. package/src/media-player/control.ts +70 -0
  723. package/src/media-player/hx.ts +51 -0
  724. package/src/media-player/index.ts +378 -0
  725. package/src/media-player/mpv.ts +146 -0
  726. package/src/media-player/vlc.ts +97 -0
  727. package/src/richtext/index.ts +42 -0
  728. package/src/richtext/links.ts +78 -0
  729. package/src/richtext/menu.ts +49 -0
  730. package/src/richtext/node.ts +406 -0
  731. package/src/richtext/runs.ts +253 -0
  732. package/src/table/hx.ts +51 -0
  733. package/src/table/index.ts +1270 -0
  734. package/src/table/rows.ts +275 -0
  735. package/src/terminal/backends.ts +242 -0
  736. package/src/terminal/hx.ts +51 -0
  737. package/src/terminal/index.ts +574 -0
  738. package/src/terminal/title.ts +172 -0
  739. package/src/terminal/vt/colors.ts +247 -0
  740. package/src/terminal/vt/diff.ts +467 -0
  741. package/src/terminal/vt/fonts.ts +233 -0
  742. package/src/terminal/vt/index.ts +443 -0
  743. package/src/terminal/vt/keys.ts +369 -0
  744. package/src/terminal/vt/mouse.ts +144 -0
  745. package/src/terminal/vt/node.ts +1242 -0
  746. package/src/terminal/vt/pty.ts +334 -0
  747. package/src/terminal/vt/renderer.ts +555 -0
  748. package/src/terminal/vt/timers.ts +31 -0
  749. package/src/terminal/vt/xterm.ts +193 -0
  750. package/src/terminal-output/hx.ts +51 -0
  751. package/src/terminal-output/index.ts +340 -0
  752. package/src/terminal-output/runs.ts +79 -0
  753. package/src/three/canvas.ts +451 -0
  754. package/src/three/events.ts +197 -0
  755. package/src/three/geometries.ts +429 -0
  756. package/src/three/globals.ts +34 -0
  757. package/src/three/hx.ts +22 -0
  758. package/src/three/index.ts +98 -0
  759. package/src/three/jsx-dev-runtime.ts +27 -0
  760. package/src/three/jsx-runtime.ts +38 -0
  761. package/src/three/jsx.ts +275 -0
  762. package/src/three/materials.ts +270 -0
  763. package/src/three/math.ts +585 -0
  764. package/src/three/objects.ts +397 -0
  765. package/src/three/passes.ts +90 -0
  766. package/src/three/postprocess.ts +677 -0
  767. package/src/three/raycast.ts +189 -0
  768. package/src/three/react-reconciler.d.ts +50 -0
  769. package/src/three/reconciler.ts +624 -0
  770. package/src/three/renderer-direct.ts +1055 -0
  771. package/src/three/renderer-indirect.ts +570 -0
  772. package/src/three/store.ts +207 -0
  773. package/src/timeline/hx.ts +31 -0
  774. package/src/timeline/index.ts +603 -0
  775. package/src/tray-host/hx.ts +51 -0
  776. package/src/tray-host/index.ts +331 -0
  777. package/src/tray-host/manager.ts +639 -0
  778. package/src/tray-host/notify.ts +102 -0
  779. package/src/tray-host/protocol.ts +235 -0
  780. package/src/tree/hx.ts +51 -0
  781. package/src/tree/index.ts +1127 -0
  782. package/src/tree/internal.ts +87 -0
  783. package/src/tree/rows.ts +334 -0
  784. package/src/index.d.ts +0 -2
  785. package/src/index.js +0 -9
  786. package/src/sparkline/index.d.ts +0 -29
  787. package/src/sparkline/index.js +0 -50
  788. package/src/sparkline/node.js +0 -72
@@ -0,0 +1,222 @@
1
+ // Where every row starts, when rows are not all the same height.
2
+ //
3
+ // **Shared between `<Tree>` and `<Table>`** — the first piece of machinery
4
+ // both virtualizers stand on (`./timers.ts` and `./scroll.ts` are the other
5
+ // two), promoted here from the vendored copy the table briefly carried
6
+ // (docs/prd-table.md records the decision). "No component imports another
7
+ // component" holds: this is shared code, not a component, and both import
8
+ // it.
9
+ //
10
+ // **Deliberately not a shared *module*.** The directory has no `index.ts`,
11
+ // so it has no subpath, no docs page, and is not public API — the repo's
12
+ // guards (`test/docs.test.ts`, `scripts/check-package.ts`) key on
13
+ // `src/<name>/index.ts`, and that is the seam this uses. The day an app
14
+ // outside this package needs a height index of its own, the promotion is
15
+ // mechanical: give the directory an `index.ts` and the full shared-module
16
+ // treatment (subpath, page, barrel), the way `richtext` has it.
17
+ //
18
+ // The id-keying earns its place twice: in the tree a measured height
19
+ // survives a collapse and re-expand, and in the table it survives a
20
+ // **re-sort** — the permutation rebuilds offsets without remeasuring a
21
+ // single row.
22
+ //
23
+ // A fixed-height list needs no structure at all: row `i` is at `i * h`, and
24
+ // the row at offset `y` is `y / h`. That one multiplication is the whole
25
+ // reason fixed-height virtualization is easy, and it is what this file
26
+ // replaces — because a tree row wraps, carries two lines, or is whatever a
27
+ // render seam returned, and demanding that they all match would be the
28
+ // component telling the application what its data may look like.
29
+ //
30
+ // What replaces it has to answer three questions on every scroll, over a
31
+ // list that may be a hundred thousand rows long:
32
+ //
33
+ // - where does row `i` start? `offsetAt`
34
+ // - which row is at offset `y`? `indexAt`
35
+ // - how tall is the whole thing? `total`
36
+ //
37
+ // A prefix-sum array answers the first and third in O(1) but costs O(n) per
38
+ // measurement, and measurements arrive in bursts — every row that scrolls
39
+ // into view is one. A Fenwick tree (binary indexed tree) answers all three in
40
+ // O(log n) and updates in O(log n), which is what makes "measure the rows
41
+ // that just appeared, then re-render" affordable at any size.
42
+
43
+ /** What a row is keyed by. `TreeItemId` and `TableRowId` are both this
44
+ * type; keeping it structural here is what lets each component keep its
45
+ * own vocabulary. */
46
+ export type RowKey = string | number;
47
+
48
+ /** All this needs of a row. Taking the rows themselves rather than an array
49
+ * of ids is what keeps `sync` free on a re-render: the component already
50
+ * memoizes the row list, so identity alone says "nothing moved". */
51
+ interface Keyed {
52
+ id: RowKey;
53
+ }
54
+
55
+ /**
56
+ * The heights of the rows, and where each one starts.
57
+ *
58
+ * Mutable and long-lived: one of these belongs to a component for as long
59
+ * as it is mounted, and `sync` re-points it at the rows a render is about
60
+ * to draw. It is deliberately **not** React state — a measurement pass
61
+ * touches it once per rendered row and the component re-renders once, on a
62
+ * version counter, and only when something actually moved.
63
+ */
64
+ export class RowHeights {
65
+ /** Measured heights, by row id. Survives `sync`. */
66
+ private readonly measured = new Map<RowKey, number>();
67
+ /** The rows currently indexed, in draw order. */
68
+ private rows: readonly Keyed[] = [];
69
+ /** Fenwick tree over the heights, 1-based. */
70
+ private tree: number[] = [0];
71
+ /** What an unmeasured row is assumed to be. */
72
+ private estimate = 1;
73
+ /** Largest power of two <= n, for the O(log n) descent in `indexAt`. */
74
+ private power = 0;
75
+ /** Set when a measurement could not be applied in place, so the next
76
+ * `sync` must rebuild even though the row list did not change. */
77
+ private dirty = false;
78
+
79
+ constructor(estimate: number) {
80
+ this.estimate = Math.max(1, estimate);
81
+ }
82
+
83
+ private heightOf(index: number): number {
84
+ const measured = this.measured.get(this.rows[index].id);
85
+ return measured === undefined ? this.estimate : measured;
86
+ }
87
+
88
+ /**
89
+ * Point the index at the rows about to be drawn.
90
+ *
91
+ * Rebuilt rather than patched, and cheap to call on every render: the row
92
+ * list is memoized, so the common case is an identity check. When it does
93
+ * rebuild it is O(n) — the rows change when a branch opens, when items
94
+ * arrive, when a sort flips, when a filter runs, all O(n) events already.
95
+ */
96
+ sync(rows: readonly Keyed[], estimate: number): void {
97
+ const next = Math.max(1, estimate);
98
+ if (!this.dirty && this.rows === rows && next === this.estimate) return;
99
+ this.dirty = false;
100
+ this.rows = rows;
101
+ this.estimate = next;
102
+ const n = rows.length;
103
+ // Build in O(n): write each height at its own slot, then push every slot
104
+ // into its parent. The textbook loop of point-updates is O(n log n) and
105
+ // arrives at the same tree.
106
+ const tree = new Array<number>(n + 1).fill(0);
107
+ for (let i = 0; i < n; i++) tree[i + 1] = this.heightOf(i);
108
+ for (let i = 1; i <= n; i++) {
109
+ const parent = i + (i & -i);
110
+ if (parent <= n) tree[parent] += tree[i];
111
+ }
112
+ this.tree = tree;
113
+ this.power = n > 0 ? 1 << Math.floor(Math.log2(n)) : 0;
114
+ }
115
+
116
+ /**
117
+ * Record what a row actually laid out at. Returns whether this changed
118
+ * anything — which is what tells the component whether to re-render, and
119
+ * the reason a measurement pass that finds nothing new costs nothing.
120
+ */
121
+ measure(id: RowKey, index: number, height: number): boolean {
122
+ if (!(height > 0)) return false;
123
+ const before = this.measured.get(id);
124
+ if (before === height) return false;
125
+ this.measured.set(id, height);
126
+ if (this.rows[index]?.id !== id) {
127
+ // The caller's index is stale — the rows moved under a measurement
128
+ // that was already in flight. Applying a delta at the wrong slot would
129
+ // corrupt every offset after it, so the tree is rebuilt instead.
130
+ this.dirty = true;
131
+ return true;
132
+ }
133
+ const delta = height - (before === undefined ? this.estimate : before);
134
+ if (delta === 0) return false;
135
+ for (let i = index + 1; i < this.tree.length; i += i & -i) {
136
+ this.tree[i] += delta;
137
+ }
138
+ return true;
139
+ }
140
+
141
+ /** What a row measured, or the estimate if it has not been seen. */
142
+ heightAt(index: number): number {
143
+ return index >= 0 && index < this.rows.length ? this.heightOf(index) : 0;
144
+ }
145
+
146
+ /** Whether this row has a real measurement rather than an estimate. */
147
+ isMeasured(index: number): boolean {
148
+ const row = this.rows[index];
149
+ return row !== undefined && this.measured.has(row.id);
150
+ }
151
+
152
+ /** Where row `index` starts. `offsetAt(rowCount)` is the total. */
153
+ offsetAt(index: number): number {
154
+ let sum = 0;
155
+ for (
156
+ let i = Math.max(0, Math.min(index, this.rows.length));
157
+ i > 0;
158
+ i -= i & -i
159
+ ) {
160
+ sum += this.tree[i];
161
+ }
162
+ return sum;
163
+ }
164
+
165
+ /** How tall the whole list is — what the scrollbar measures. */
166
+ total(): number {
167
+ return this.offsetAt(this.rows.length);
168
+ }
169
+
170
+ /**
171
+ * The row containing `offset`, clamped into the list.
172
+ *
173
+ * A descent down the tree rather than a binary search over `offsetAt`,
174
+ * which would be O(log² n) — this is the operation every scroll performs,
175
+ * twice.
176
+ */
177
+ indexAt(offset: number): number {
178
+ const n = this.rows.length;
179
+ if (n === 0) return 0;
180
+ let index = 0;
181
+ let remaining = offset;
182
+ for (let step = this.power; step > 0; step >>= 1) {
183
+ const next = index + step;
184
+ if (next <= n && this.tree[next] <= remaining) {
185
+ index = next;
186
+ remaining -= this.tree[next];
187
+ }
188
+ }
189
+ return Math.max(0, Math.min(n - 1, index));
190
+ }
191
+
192
+ /**
193
+ * Whether anything has ever been measured — O(1), and the question a
194
+ * component that may not measure at all has to ask before it waits on a
195
+ * measurement. `measuredCount` answers a different, costlier question:
196
+ * how many of the rows *currently indexed* have one.
197
+ */
198
+ hasMeasurements(): boolean {
199
+ return this.measured.size > 0;
200
+ }
201
+
202
+ /** How many of the current rows have a real measurement. */
203
+ measuredCount(): number {
204
+ let count = 0;
205
+ for (const row of this.rows) if (this.measured.has(row.id)) count++;
206
+ return count;
207
+ }
208
+
209
+ /**
210
+ * Forget every measurement, keeping the row list.
211
+ *
212
+ * For a change that invalidates heights wholesale rather than row by row.
213
+ * Nothing calls it for new items — their ids are simply not in the map yet
214
+ * — and nothing calls it on a resize either: rows re-measure as they are
215
+ * drawn, and throwing away the heights of rows whose content does not
216
+ * depend on the width would make the scrollbar worse, not better.
217
+ */
218
+ reset(): void {
219
+ this.measured.clear();
220
+ this.dirty = true;
221
+ }
222
+ }
@@ -0,0 +1,53 @@
1
+ // `React.createElement`, typed against react-x11's host elements.
2
+ //
3
+ // The library writes `h(...)` rather than JSX — a convention inherited from
4
+ // core, and worth keeping so moving code between the two repos stays a
5
+ // rename. Shared by every composed widget out here (`<Calendar>`,
6
+ // `<DatePicker>`, `<ColorPicker>`, `<ColorField>`), which is why it sits in
7
+ // `src/internal/` rather than in one of them. But `React.createElement`'s own overloads are `@types/react`'s, and
8
+ // they describe the DOM: a `<box onKeyDown>` handler is checked against
9
+ // React's `KeyboardEvent`, not react-x11's, and the whole props object is
10
+ // measured against `DOMAttributes`. Everything interesting fails.
11
+ //
12
+ // So the element name is looked up in react-x11's own element table instead.
13
+ // `hx('box', …)` gets `<box>`'s real props — `ev.keysym` on a key handler,
14
+ // `onDraw` on a `<canvas>` — and `hx('div', …)` is an error, which is the
15
+ // same guarantee the JSX namespace gives `examples/` and `test/types/`.
16
+ import React from 'react';
17
+ import type { Key, ReactElement, ReactNode } from 'react';
18
+ import type { ReactX11Elements, Theme } from 'react-x11';
19
+
20
+ /** The host elements, by name. */
21
+ export type Host = ReactX11Elements;
22
+
23
+ /**
24
+ * What every element takes on top of its own props.
25
+ *
26
+ * `theme` is honoured by **every** node — `Node.theme` merges `props.theme`
27
+ * over the inherited palette, whatever the kind — but react-x11's element
28
+ * declarations only put it on `<window>`. A widget re-declares the theme it
29
+ * read from context onto its own root so that `$token` values still resolve
30
+ * inside a `<popup>`, which is a separate window and does not inherit the
31
+ * trigger's node tree. So the prop is real; only the declaration is narrow.
32
+ */
33
+ interface CommonProps {
34
+ key?: Key;
35
+ /** `Theme` is listed alongside the record because it is an interface, and
36
+ * an interface has no implicit index signature — so the palette `useTheme`
37
+ * hands back is not assignable to the record react-x11 declares. */
38
+ theme?: Theme | Record<string, string | number>;
39
+ }
40
+
41
+ export function hx<K extends keyof Host>(
42
+ type: K,
43
+ // `theme` is dropped from the element's own props before the merge:
44
+ // `<window>` and `<popup>` already declare it, narrower, and intersecting
45
+ // the two would demand a value satisfying both.
46
+ props?: (Omit<Host[K], 'theme'> & CommonProps) | null,
47
+ ...children: ReactNode[]
48
+ ): ReactElement {
49
+ // The cast is the whole point of the wrapper: `createElement`'s string
50
+ // overload insists on DOM props, and the signature above has already
51
+ // checked these against the element that will actually receive them.
52
+ return React.createElement(type as string, props as never, ...children);
53
+ }
@@ -0,0 +1,288 @@
1
+ // Scrolling a row into view, when neither the row nor the scroll pane is
2
+ // ready to be asked yet.
3
+ //
4
+ // **Shared between `<Tree>` and `<Table>`** — the third piece both
5
+ // virtualizers stand on, beside `./heights.ts` and `./timers.ts`, and here
6
+ // for the same reason: the logic is subtle, it is identical in both, and a
7
+ // second copy of it is a second place for the bug below to come back.
8
+ //
9
+ // Two things a scroll pane does silently, both of them in the gap between a
10
+ // commit and the layout it causes, and both of them enough on their own to
11
+ // leave a virtualized list drawing rows the viewport is no longer looking at:
12
+ //
13
+ // 1. **`scrollTo` clamps against the content height the *last* layout
14
+ // measured.** A row appended in the commit now being laid out is past
15
+ // the bottom that clamp knows about, so the request lands short — and
16
+ // short *for good*, because nothing about it is retried. That is the
17
+ // live tail: a list that scrolls to its newest row on every update and
18
+ // settles one update behind, permanently. On mount, where no content
19
+ // has been laid out at all, the scroll simply never happens.
20
+ //
21
+ // 2. **The pane moves without saying so.** It resolves a queued
22
+ // `scrollIntoView` during layout, and it re-clamps an offset the
23
+ // content has outgrown or outshrunk — neither of which fires
24
+ // `onScroll`. A component that learns the offset only from that event
25
+ // keeps building its slice from where the pane *was*: the rows are
26
+ // drawn off-viewport, there is a blank band where they should be, and
27
+ // nothing puts it right until a scroll of your own re-syncs it by
28
+ // accident.
29
+ //
30
+ // So a reveal here is not a one-shot: it is a **debt**, kept by row id,
31
+ // attempted at once and re-tried on the layout that makes the rest of the
32
+ // move possible. It is dropped as soon as the row is in view, leaves the
33
+ // list, or the user scrolls somewhere themselves — an owed scroll must never
34
+ // yank the list back out from under a hand on the wheel.
35
+ //
36
+ // The offset is read back from the pane rather than trusted to the event;
37
+ // `useReveal` does not do that itself, because what a component *does* with
38
+ // the offset differs (a slice to rebuild, a header to shift), but it is the
39
+ // other half of the same fix and both components run it on the same tick.
40
+
41
+ import { useCallback, useEffect, useRef } from 'react';
42
+ import type { DrawnNode, ScrollableNode } from 'react-x11';
43
+
44
+ import type { RowHeights, RowKey } from './heights.js';
45
+ import { afterLayout, cancelAfterLayout } from './timers.js';
46
+ import type { LayoutTick } from './timers.js';
47
+
48
+ /** All a reveal needs of a row: `<TreeRow>` and `<TableRow>` are both this. */
49
+ interface Keyed {
50
+ id: RowKey;
51
+ }
52
+
53
+ /** A row on screen, and the index it was drawn at — the shape both
54
+ * components already keep their mounted rows in. */
55
+ interface Drawn {
56
+ node: DrawnNode;
57
+ at: number;
58
+ }
59
+
60
+ /** What the component lends the reveal: everything it already has, by ref,
61
+ * so nothing here goes stale between a render and the tick after layout. */
62
+ export interface RevealSources {
63
+ /** The scroll pane. `<Table>`'s body; `<Tree>`'s own root. */
64
+ box: { readonly current: ScrollableNode | null };
65
+ /** The rows in display order. */
66
+ rows: { readonly current: readonly Keyed[] };
67
+ /** The rows on screen, by id. */
68
+ nodes: { readonly current: ReadonlyMap<RowKey, Drawn> };
69
+ /** Where the rows that are *not* on screen are — and how tall a row that
70
+ * has never been drawn is assumed to be. */
71
+ heights: RowHeights;
72
+ }
73
+
74
+ export interface Reveal {
75
+ /** Owe a scroll to this row, and try to pay it now. */
76
+ to(id: RowKey): void;
77
+ /**
78
+ * Try again: after a layout, or when the content changed size.
79
+ *
80
+ * Pass `provisional` on a pass where the height index just moved. The rows
81
+ * are still laid out at the heights it no longer believes, so a row that
82
+ * looks in view is not proof of anything yet — a row measured taller than
83
+ * the guess pushes everything after it down, and the row that was reached a
84
+ * moment ago ends up under the fold. The debt is kept until a pass that
85
+ * measured nothing new confirms it, which is exactly when the heights have
86
+ * converged.
87
+ */
88
+ retry(provisional?: boolean): void;
89
+ /** Scroll the pane, recording that this component is the one that asked. */
90
+ scrollTo(y: number): void;
91
+ /** An `onScroll` arrived. One this component did not ask for is the user
92
+ * taking over, and it cancels whatever was owed. */
93
+ heard(scrollY: number): void;
94
+ }
95
+
96
+ /**
97
+ * The scroll a component owes a row, and the bookkeeping that pays it.
98
+ *
99
+ * Stable across renders — every method reads through the refs it was handed,
100
+ * so an event handler or a layout tick built in an earlier render still sees
101
+ * the current rows.
102
+ */
103
+ export function useReveal(sources: RevealSources): Reveal {
104
+ const src = useRef(sources);
105
+ src.current = sources;
106
+ /** The row still owed a scroll, by id. */
107
+ const owed = useRef<RowKey | null>(null);
108
+ /**
109
+ * The row the last reveal settled on, kept for one reason: a measurement
110
+ * pass can move the heights that settlement was judged against. A row that
111
+ * was in view when the debt was paid is not in view any more once the rows
112
+ * around it turn out taller than the index believed, and the honest answer
113
+ * to "is that still true?" is to owe it again and look. Measurement
114
+ * converges, so this stops asking.
115
+ */
116
+ const settled = useRef<RowKey | null>(null);
117
+ /** The offset the last scroll *this component* asked for, so the
118
+ * `onScroll` that answers it is not read as the user taking over. */
119
+ const asked = useRef<number | null>(null);
120
+ /**
121
+ * What the pane looked like at the last attempt that could not move.
122
+ *
123
+ * An attempt clamped by a content height that is a layout out of date has
124
+ * to be looked at again — and nothing else will schedule that look: the
125
+ * scroll that did not happen renders nothing, so the component's own tick
126
+ * after layout never comes. One is queued here instead, and only while the
127
+ * pane keeps changing under it: an attempt that finds the same offset and
128
+ * the same content as the last one has nothing new to try, and stops.
129
+ */
130
+ const stuck = useRef<{ y: number; content: number } | null>(null);
131
+ const look = useRef<LayoutTick>(null);
132
+ useEffect(() => () => cancelAfterLayout(look.current), []);
133
+
134
+ const scrollTo = useCallback((y: number): void => {
135
+ const box = src.current.box.current;
136
+ if (!box) return;
137
+ // Clamped here rather than left to the container, so what comes back on
138
+ // `onScroll` is the number that was asked for and can be recognised.
139
+ const to = Math.min(
140
+ Math.max(0, y),
141
+ Math.max(0, box.contentHeight - box.abs.height),
142
+ );
143
+ if (to === box.scrollY) return;
144
+ asked.current = to;
145
+ box.scrollTo({ y: to });
146
+ }, []);
147
+
148
+ const retry = useCallback(
149
+ (provisional?: boolean): void => {
150
+ const { box: boxRef, rows: rowsRef, nodes, heights } = src.current;
151
+ const box = boxRef.current;
152
+ // The heights just moved, so what the last reveal settled on was settled
153
+ // against numbers that have changed: owe it again until it can be
154
+ // confirmed at the new ones.
155
+ if (provisional && owed.current === null) owed.current = settled.current;
156
+ const id = owed.current;
157
+ if (!box || id === null) return;
158
+ const rows = rowsRef.current;
159
+ const at = rows.findIndex((r) => r.id === id);
160
+ if (at < 0) {
161
+ // the row left the list
162
+ owed.current = null;
163
+ settled.current = null;
164
+ return;
165
+ }
166
+ const viewport = box.abs.height;
167
+ if (viewport <= 0) return; // nothing laid out to scroll inside yet
168
+
169
+ // How far the row is outside the pane, in pixels of scrolling. The row's
170
+ // own rect answers when it is mounted — it knows what it really laid out
171
+ // at, and the arithmetic stays in screen coordinates, so a pane with
172
+ // padding on it needs no correction. The height index answers when the
173
+ // row is not mounted, which while virtualizing is the normal case.
174
+ const drawn = nodes.current.get(id);
175
+ const mounted =
176
+ drawn && drawn.node.abs.height > 0 && rows[drawn.at]?.id === id
177
+ ? drawn.node
178
+ : null;
179
+ const placed = mounted
180
+ ? {
181
+ above: box.abs.y - mounted.abs.y,
182
+ below: mounted.abs.y + mounted.abs.height - (box.abs.y + viewport),
183
+ height: mounted.abs.height,
184
+ }
185
+ : {
186
+ above: box.scrollY - heights.offsetAt(at),
187
+ below:
188
+ heights.offsetAt(at) +
189
+ heights.heightAt(at) -
190
+ (box.scrollY + viewport),
191
+ height: heights.heightAt(at),
192
+ };
193
+ /**
194
+ * Whether this is worth *settling* on, or only worth acting on.
195
+ *
196
+ * Two ways a row can look in view and not stay there. Its own placement
197
+ * may be a guess — the index's answer for a row nothing has measured —
198
+ * and "in view" judged from a guess is how a tail lands short of a bottom
199
+ * that has not been measured yet. Or a row *between* the viewport and it
200
+ * may still be a guess, and every one of those that turns out taller than
201
+ * the index believed pushes this row down by the difference, out of the
202
+ * view it had just been brought into.
203
+ *
204
+ * Both are settled by the same thing: measurement converges, so the rows
205
+ * that matter stop being guesses. A component that measures nothing at all
206
+ * has no guesses to wait on — `hasMeasurements` is how that is told
207
+ * apart, and it is what keeps a declared-uniform table from owing a debt
208
+ * for ever.
209
+ */
210
+ let certain = mounted !== null || heights.isMeasured(at);
211
+ if (certain && heights.hasMeasurements()) {
212
+ const from = Math.min(at, heights.indexAt(box.scrollY));
213
+ const to = Math.max(at, heights.indexAt(box.scrollY + viewport));
214
+ for (let i = from; i <= to && certain; i++) {
215
+ certain = heights.isMeasured(i);
216
+ }
217
+ }
218
+
219
+ let move = 0;
220
+ if (placed.height >= viewport) {
221
+ // A row taller than the pane is never *fully* in view, and asking for
222
+ // both its edges in turn is a debt that alternates for ever. Its top is
223
+ // the part worth showing — a wrapped row reads from its first line —
224
+ // and arriving there settles it.
225
+ move = -placed.above;
226
+ } else if (placed.above > 0) move = -placed.above;
227
+ else if (placed.below > 0) move = placed.below;
228
+
229
+ if (move === 0) {
230
+ // As far in view as it can be — settled, unless what that was judged
231
+ // against is still moving: a placement that came from a guess, or a
232
+ // pass that has just changed the heights under it.
233
+ if (certain && !provisional) {
234
+ settled.current = id;
235
+ owed.current = null;
236
+ }
237
+ return;
238
+ }
239
+ // A move the pane cannot make yet leaves the debt standing: the layout
240
+ // that admits the rows just appended is the one that will let it finish.
241
+ const was = box.scrollY;
242
+ scrollTo(was + move);
243
+ if (box.scrollY !== was) {
244
+ stuck.current = null; // it moved; the scroll it caused brings us back
245
+ return;
246
+ }
247
+ const seen = stuck.current;
248
+ const now = { y: box.scrollY, content: box.contentHeight };
249
+ stuck.current = now;
250
+ if (seen && seen.y === now.y && seen.content === now.content) return;
251
+ cancelAfterLayout(look.current);
252
+ look.current = afterLayout(() => {
253
+ look.current = null;
254
+ retryRef.current?.();
255
+ });
256
+ },
257
+ [scrollTo],
258
+ );
259
+
260
+ /** `retry` referring to itself through a ref, so the queued look calls the
261
+ * current one rather than closing over the render that queued it. */
262
+ const retryRef = useRef<(() => void) | null>(null);
263
+ retryRef.current = retry;
264
+
265
+ const to = useCallback(
266
+ (id: RowKey): void => {
267
+ // Recorded before the attempt rather than after it, because the
268
+ // interesting case is the one that cannot succeed yet.
269
+ owed.current = id;
270
+ settled.current = null;
271
+ stuck.current = null;
272
+ retry();
273
+ },
274
+ [retry],
275
+ );
276
+
277
+ const heard = useCallback((scrollY: number): void => {
278
+ // A scroll this component did not ask for ends the whole chase, not just
279
+ // the outstanding half of it.
280
+ if (scrollY !== asked.current) {
281
+ owed.current = null;
282
+ settled.current = null;
283
+ }
284
+ asked.current = null;
285
+ }, []);
286
+
287
+ return { to, retry, scrollTo, heard };
288
+ }
@@ -0,0 +1,44 @@
1
+ // The bits `<richtext>` and `<Html>` need that react-x11 has but does not
2
+ // export. Same situation, and the same shape, as `src/calendar/internal.ts` —
3
+ // each is small and pure, and if core ever puts one on its exports map,
4
+ // delete it from here and import it. `tint` was the first to go that way: it
5
+ // is `react-x11/style`'s now, and the surfaces here import it from there.
6
+ //
7
+ // It sits in `src/internal/` rather than in `src/richtext/` because two
8
+ // things share it now — the shared module and `src/html/`'s own layout — and
9
+ // that is exactly what this directory is for (AGENTS.md, "the half-step below
10
+ // a shared module").
11
+
12
+ // --- code points vs code units ---------------------------------------------
13
+ //
14
+ // ntk's line runs report their extent in **code units** while its caret API
15
+ // speaks **code points**, so anything reading run geometry has to translate.
16
+ // Core has exactly these two functions in `src/textrange.js` (react-x11#291)
17
+ // and its `<text>` uses them for the same purpose; they are copied rather
18
+ // than imported because that module is not on core's exports map. Delete
19
+ // them the day it is.
20
+
21
+ /** Code point index -> UTF-16 offset, with one extra entry for the end. */
22
+ export function codeUnitOffsets(text: string): number[] {
23
+ const offsets: number[] = [];
24
+ const s = text ?? '';
25
+ for (let i = 0; i < s.length;) {
26
+ offsets.push(i);
27
+ i += (s.codePointAt(i) ?? 0) > 0xffff ? 2 : 1;
28
+ }
29
+ offsets.push(s.length);
30
+ return offsets;
31
+ }
32
+
33
+ /** The code point index for a UTF-16 offset, rounded down to a whole
34
+ * character. Binary search over `codeUnitOffsets`. */
35
+ export function codePointAtOffset(offsets: number[], offset: number): number {
36
+ let lo = 0;
37
+ let hi = offsets.length - 1;
38
+ while (lo < hi) {
39
+ const mid = (lo + hi + 1) >> 1;
40
+ if (offsets[mid] <= offset) lo = mid;
41
+ else hi = mid - 1;
42
+ }
43
+ return lo;
44
+ }
@@ -0,0 +1,44 @@
1
+ // "Run this once layout has happened", reached through `globalThis`.
2
+ //
3
+ // **Shared between `<Tree>` and `<Table>`** — promoted here with the height
4
+ // index beside it; see `./heights.ts` for why this directory is internal
5
+ // rather than a shared module with a subpath.
6
+ //
7
+ // The build compiles `src/` with `types: []` on purpose — a Node global that
8
+ // wanders in must fail the build rather than become an implicit
9
+ // `@types/node` dependency (AGENTS.md) — so the one timer virtualization
10
+ // needs is typed here, structurally, the way `../code-language/timers.ts`
11
+ // does it.
12
+ //
13
+ // **Why a tick and not an effect.** react-x11 lays out on a frame flush, not
14
+ // in the commit, so a `useLayoutEffect` or a `useEffect` reads the geometry of
15
+ // the *previous* pass: on the render that created a row, `node.abs.height` is
16
+ // still 0. A macrotask scheduled from an effect lands after the flush, which
17
+ // is the first moment a row can be asked how tall it turned out to be.
18
+ interface Deferred {
19
+ setImmediate?(fn: () => void): unknown;
20
+ clearImmediate?(id: unknown): void;
21
+ setTimeout?(fn: () => void, ms: number): unknown;
22
+ clearTimeout?(id: unknown): void;
23
+ }
24
+
25
+ const g = globalThis as Deferred;
26
+
27
+ export type LayoutTick = { immediate: boolean; id: unknown } | null;
28
+
29
+ /** Run `fn` after the layout pass this commit will cause. */
30
+ export function afterLayout(fn: () => void): LayoutTick {
31
+ // `setImmediate` is the check-phase callback, which runs after the frame
32
+ // work node has already queued. `setTimeout(0)` is the fallback for a host
33
+ // that has no `setImmediate` — a browser-shaped global object, or a
34
+ // stripped-down runtime — and lands in the same place for this purpose.
35
+ if (g.setImmediate) return { immediate: true, id: g.setImmediate(fn) };
36
+ if (g.setTimeout) return { immediate: false, id: g.setTimeout(fn, 0) };
37
+ return null;
38
+ }
39
+
40
+ export function cancelAfterLayout(tick: LayoutTick): void {
41
+ if (!tick) return;
42
+ if (tick.immediate) g.clearImmediate?.(tick.id);
43
+ else g.clearTimeout?.(tick.id);
44
+ }