@react-x11/components 0.9.0 → 0.10.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 (550) hide show
  1. package/README.md +10 -4
  2. package/dist/charts/node.d.ts +11 -1
  3. package/dist/charts/node.d.ts.map +1 -1
  4. package/dist/charts/node.js +44 -14
  5. package/dist/charts/node.js.map +1 -1
  6. package/dist/charts/render.d.ts +12 -3
  7. package/dist/charts/render.d.ts.map +1 -1
  8. package/dist/charts/render.js +94 -25
  9. package/dist/charts/render.js.map +1 -1
  10. package/dist/code/index.d.ts.map +1 -1
  11. package/dist/code/index.js +3 -1
  12. package/dist/code/index.js.map +1 -1
  13. package/dist/code-editor/completion.d.ts.map +1 -1
  14. package/dist/code-editor/completion.js +3 -2
  15. package/dist/code-editor/completion.js.map +1 -1
  16. package/dist/code-editor/index.d.ts.map +1 -1
  17. package/dist/code-editor/index.js +19 -0
  18. package/dist/code-editor/index.js.map +1 -1
  19. package/dist/code-editor/node.d.ts +177 -7
  20. package/dist/code-editor/node.d.ts.map +1 -1
  21. package/dist/code-editor/node.js +1329 -164
  22. package/dist/code-editor/node.js.map +1 -1
  23. package/dist/code-language/languages/glsl.d.ts.map +1 -1
  24. package/dist/code-language/languages/glsl.js +10 -2
  25. package/dist/code-language/languages/glsl.js.map +1 -1
  26. package/dist/code-language/languages/javascript.d.ts.map +1 -1
  27. package/dist/code-language/languages/javascript.js +18 -3
  28. package/dist/code-language/languages/javascript.js.map +1 -1
  29. package/dist/code-language/languages/json.d.ts.map +1 -1
  30. package/dist/code-language/languages/json.js +10 -2
  31. package/dist/code-language/languages/json.js.map +1 -1
  32. package/dist/code-language/languages/shell.d.ts.map +1 -1
  33. package/dist/code-language/languages/shell.js +10 -2
  34. package/dist/code-language/languages/shell.js.map +1 -1
  35. package/dist/code-language/languages/sql.d.ts.map +1 -1
  36. package/dist/code-language/languages/sql.js +20 -2
  37. package/dist/code-language/languages/sql.js.map +1 -1
  38. package/dist/code-language/stream.d.ts +22 -0
  39. package/dist/code-language/stream.d.ts.map +1 -1
  40. package/dist/code-language/stream.js +259 -9
  41. package/dist/code-language/stream.js.map +1 -1
  42. package/dist/code-language/types.d.ts +5 -4
  43. package/dist/code-language/types.d.ts.map +1 -1
  44. package/dist/codeblock/index.d.ts +13 -2
  45. package/dist/codeblock/index.d.ts.map +1 -1
  46. package/dist/codeblock/index.js +20 -3
  47. package/dist/codeblock/index.js.map +1 -1
  48. package/dist/flow/draw.d.ts +50 -0
  49. package/dist/flow/draw.d.ts.map +1 -1
  50. package/dist/flow/draw.js +132 -33
  51. package/dist/flow/draw.js.map +1 -1
  52. package/dist/flow/gl/color.d.ts +13 -0
  53. package/dist/flow/gl/color.d.ts.map +1 -0
  54. package/dist/flow/gl/color.js +82 -0
  55. package/dist/flow/gl/color.js.map +1 -0
  56. package/dist/flow/gl/index.d.ts +60 -0
  57. package/dist/flow/gl/index.d.ts.map +1 -0
  58. package/dist/flow/gl/index.js +283 -0
  59. package/dist/flow/gl/index.js.map +1 -0
  60. package/dist/flow/gl/pack.d.ts +133 -0
  61. package/dist/flow/gl/pack.d.ts.map +1 -0
  62. package/dist/flow/gl/pack.js +408 -0
  63. package/dist/flow/gl/pack.js.map +1 -0
  64. package/dist/flow/gl/renderer.d.ts +95 -0
  65. package/dist/flow/gl/renderer.d.ts.map +1 -0
  66. package/dist/flow/gl/renderer.js +459 -0
  67. package/dist/flow/gl/renderer.js.map +1 -0
  68. package/dist/flow/gl/shaders.d.ts +79 -0
  69. package/dist/flow/gl/shaders.d.ts.map +1 -0
  70. package/dist/flow/gl/shaders.js +346 -0
  71. package/dist/flow/gl/shaders.js.map +1 -0
  72. package/dist/flow/gl/text.d.ts +318 -0
  73. package/dist/flow/gl/text.d.ts.map +1 -0
  74. package/dist/flow/gl/text.js +1103 -0
  75. package/dist/flow/gl/text.js.map +1 -0
  76. package/dist/flow/index.d.ts +1 -1
  77. package/dist/flow/index.d.ts.map +1 -1
  78. package/dist/flow/index.js +619 -64
  79. package/dist/flow/index.js.map +1 -1
  80. package/dist/flow/node.d.ts +621 -72
  81. package/dist/flow/node.d.ts.map +1 -1
  82. package/dist/flow/node.js +2253 -1018
  83. package/dist/flow/node.js.map +1 -1
  84. package/dist/flow/paint.d.ts +35 -0
  85. package/dist/flow/paint.d.ts.map +1 -0
  86. package/dist/flow/paint.js +393 -0
  87. package/dist/flow/paint.js.map +1 -0
  88. package/dist/flow/paths.d.ts +14 -0
  89. package/dist/flow/paths.d.ts.map +1 -1
  90. package/dist/flow/paths.js +45 -19
  91. package/dist/flow/paths.js.map +1 -1
  92. package/dist/flow/scene.d.ts +584 -0
  93. package/dist/flow/scene.d.ts.map +1 -0
  94. package/dist/flow/scene.js +1453 -0
  95. package/dist/flow/scene.js.map +1 -0
  96. package/dist/flow/types.d.ts +111 -1
  97. package/dist/flow/types.d.ts.map +1 -1
  98. package/dist/html/controls.d.ts +28 -0
  99. package/dist/html/controls.d.ts.map +1 -1
  100. package/dist/html/controls.js +52 -2
  101. package/dist/html/controls.js.map +1 -1
  102. package/dist/html/css/calc.d.ts +14 -0
  103. package/dist/html/css/calc.d.ts.map +1 -0
  104. package/dist/html/css/calc.js +344 -0
  105. package/dist/html/css/calc.js.map +1 -0
  106. package/dist/html/css/cascade.d.ts +240 -6
  107. package/dist/html/css/cascade.d.ts.map +1 -1
  108. package/dist/html/css/cascade.js +1327 -66
  109. package/dist/html/css/cascade.js.map +1 -1
  110. package/dist/html/css/color.d.ts +23 -0
  111. package/dist/html/css/color.d.ts.map +1 -0
  112. package/dist/html/css/color.js +740 -0
  113. package/dist/html/css/color.js.map +1 -0
  114. package/dist/html/css/content.d.ts +92 -0
  115. package/dist/html/css/content.d.ts.map +1 -0
  116. package/dist/html/css/content.js +388 -0
  117. package/dist/html/css/content.js.map +1 -0
  118. package/dist/html/css/counter-styles.d.ts +76 -0
  119. package/dist/html/css/counter-styles.d.ts.map +1 -0
  120. package/dist/html/css/counter-styles.js +893 -0
  121. package/dist/html/css/counter-styles.js.map +1 -0
  122. package/dist/html/css/decode.d.ts +12 -0
  123. package/dist/html/css/decode.d.ts.map +1 -0
  124. package/dist/html/css/decode.js +116 -0
  125. package/dist/html/css/decode.js.map +1 -0
  126. package/dist/html/css/parse.d.ts +110 -10
  127. package/dist/html/css/parse.d.ts.map +1 -1
  128. package/dist/html/css/parse.js +1473 -180
  129. package/dist/html/css/parse.js.map +1 -1
  130. package/dist/html/css/style.d.ts +498 -15
  131. package/dist/html/css/style.d.ts.map +1 -1
  132. package/dist/html/css/style.js +3698 -206
  133. package/dist/html/css/style.js.map +1 -1
  134. package/dist/html/css/ua.d.ts.map +1 -1
  135. package/dist/html/css/ua.js +57 -11
  136. package/dist/html/css/ua.js.map +1 -1
  137. package/dist/html/css/values.d.ts +37 -3
  138. package/dist/html/css/values.d.ts.map +1 -1
  139. package/dist/html/css/values.js +122 -48
  140. package/dist/html/css/values.js.map +1 -1
  141. package/dist/html/css/vars.d.ts +52 -0
  142. package/dist/html/css/vars.d.ts.map +1 -0
  143. package/dist/html/css/vars.js +358 -0
  144. package/dist/html/css/vars.js.map +1 -0
  145. package/dist/html/dom.d.ts +30 -4
  146. package/dist/html/dom.d.ts.map +1 -1
  147. package/dist/html/dom.js +278 -17
  148. package/dist/html/dom.js.map +1 -1
  149. package/dist/html/fonts.d.ts +106 -0
  150. package/dist/html/fonts.d.ts.map +1 -0
  151. package/dist/html/fonts.js +565 -0
  152. package/dist/html/fonts.js.map +1 -0
  153. package/dist/html/gif.d.ts +15 -0
  154. package/dist/html/gif.d.ts.map +1 -0
  155. package/dist/html/gif.js +229 -0
  156. package/dist/html/gif.js.map +1 -0
  157. package/dist/html/index.d.ts +50 -11
  158. package/dist/html/index.d.ts.map +1 -1
  159. package/dist/html/index.js +115 -9
  160. package/dist/html/index.js.map +1 -1
  161. package/dist/html/layout/block.d.ts +226 -3
  162. package/dist/html/layout/block.d.ts.map +1 -1
  163. package/dist/html/layout/block.js +2937 -197
  164. package/dist/html/layout/block.js.map +1 -1
  165. package/dist/html/layout/boxes.d.ts +340 -17
  166. package/dist/html/layout/boxes.d.ts.map +1 -1
  167. package/dist/html/layout/boxes.js +1714 -182
  168. package/dist/html/layout/boxes.js.map +1 -1
  169. package/dist/html/layout/cache.d.ts +58 -0
  170. package/dist/html/layout/cache.d.ts.map +1 -0
  171. package/dist/html/layout/cache.js +224 -0
  172. package/dist/html/layout/cache.js.map +1 -0
  173. package/dist/html/layout/collapse.d.ts +45 -0
  174. package/dist/html/layout/collapse.d.ts.map +1 -0
  175. package/dist/html/layout/collapse.js +246 -0
  176. package/dist/html/layout/collapse.js.map +1 -0
  177. package/dist/html/layout/css-grid.d.ts +7 -0
  178. package/dist/html/layout/css-grid.d.ts.map +1 -0
  179. package/dist/html/layout/css-grid.js +900 -0
  180. package/dist/html/layout/css-grid.js.map +1 -0
  181. package/dist/html/layout/flex.d.ts.map +1 -1
  182. package/dist/html/layout/flex.js +1025 -89
  183. package/dist/html/layout/flex.js.map +1 -1
  184. package/dist/html/layout/floats.d.ts +45 -6
  185. package/dist/html/layout/floats.d.ts.map +1 -1
  186. package/dist/html/layout/floats.js +113 -14
  187. package/dist/html/layout/floats.js.map +1 -1
  188. package/dist/html/layout/grid-lines.d.ts +39 -0
  189. package/dist/html/layout/grid-lines.d.ts.map +1 -0
  190. package/dist/html/layout/grid-lines.js +119 -0
  191. package/dist/html/layout/grid-lines.js.map +1 -0
  192. package/dist/html/layout/grid.d.ts +53 -0
  193. package/dist/html/layout/grid.d.ts.map +1 -0
  194. package/dist/html/layout/grid.js +153 -0
  195. package/dist/html/layout/grid.js.map +1 -0
  196. package/dist/html/layout/inline.d.ts +151 -1
  197. package/dist/html/layout/inline.d.ts.map +1 -1
  198. package/dist/html/layout/inline.js +3375 -174
  199. package/dist/html/layout/inline.js.map +1 -1
  200. package/dist/html/layout/shaping.d.ts +6 -0
  201. package/dist/html/layout/shaping.d.ts.map +1 -0
  202. package/dist/html/layout/shaping.js +100 -0
  203. package/dist/html/layout/shaping.js.map +1 -0
  204. package/dist/html/layout/table.d.ts +3 -0
  205. package/dist/html/layout/table.d.ts.map +1 -1
  206. package/dist/html/layout/table.js +681 -175
  207. package/dist/html/layout/table.js.map +1 -1
  208. package/dist/html/layout/tracks.d.ts +44 -0
  209. package/dist/html/layout/tracks.d.ts.map +1 -0
  210. package/dist/html/layout/tracks.js +349 -0
  211. package/dist/html/layout/tracks.js.map +1 -0
  212. package/dist/html/node.d.ts +169 -4
  213. package/dist/html/node.d.ts.map +1 -1
  214. package/dist/html/node.js +1331 -100
  215. package/dist/html/node.js.map +1 -1
  216. package/dist/html/paint.d.ts +92 -3
  217. package/dist/html/paint.d.ts.map +1 -1
  218. package/dist/html/paint.js +3503 -141
  219. package/dist/html/paint.js.map +1 -1
  220. package/dist/html/resources.d.ts +60 -14
  221. package/dist/html/resources.d.ts.map +1 -1
  222. package/dist/html/resources.js +122 -36
  223. package/dist/html/resources.js.map +1 -1
  224. package/dist/html/surfaces.d.ts +23 -0
  225. package/dist/html/surfaces.d.ts.map +1 -0
  226. package/dist/html/surfaces.js +68 -0
  227. package/dist/html/surfaces.js.map +1 -0
  228. package/dist/html/svg.d.ts +80 -0
  229. package/dist/html/svg.d.ts.map +1 -0
  230. package/dist/html/svg.js +435 -0
  231. package/dist/html/svg.js.map +1 -0
  232. package/dist/html/url.d.ts +23 -0
  233. package/dist/html/url.d.ts.map +1 -0
  234. package/dist/html/url.js +80 -0
  235. package/dist/html/url.js.map +1 -0
  236. package/dist/index.d.ts +1 -1
  237. package/dist/index.d.ts.map +1 -1
  238. package/dist/index.js.map +1 -1
  239. package/dist/internal/collate.d.ts +3 -0
  240. package/dist/internal/collate.d.ts.map +1 -0
  241. package/dist/internal/collate.js +11 -0
  242. package/dist/internal/collate.js.map +1 -0
  243. package/dist/internal/markdown/ast.d.ts +11 -0
  244. package/dist/internal/markdown/ast.d.ts.map +1 -1
  245. package/dist/internal/markdown/parse.d.ts.map +1 -1
  246. package/dist/internal/markdown/parse.js +109 -8
  247. package/dist/internal/markdown/parse.js.map +1 -1
  248. package/dist/internal/prewarm.d.ts +18 -0
  249. package/dist/internal/prewarm.d.ts.map +1 -0
  250. package/dist/internal/prewarm.js +42 -0
  251. package/dist/internal/prewarm.js.map +1 -0
  252. package/dist/internal/sdf.d.ts +20 -0
  253. package/dist/internal/sdf.d.ts.map +1 -0
  254. package/dist/internal/sdf.js +216 -0
  255. package/dist/internal/sdf.js.map +1 -0
  256. package/dist/internal/splice.d.ts +12 -0
  257. package/dist/internal/splice.d.ts.map +1 -0
  258. package/dist/internal/splice.js +23 -0
  259. package/dist/internal/splice.js.map +1 -0
  260. package/dist/internal/window.d.ts +12 -0
  261. package/dist/internal/window.d.ts.map +1 -1
  262. package/dist/internal/window.js +23 -6
  263. package/dist/internal/window.js.map +1 -1
  264. package/dist/maps/anchors.d.ts +6 -1
  265. package/dist/maps/anchors.d.ts.map +1 -1
  266. package/dist/maps/anchors.js +260 -1
  267. package/dist/maps/anchors.js.map +1 -1
  268. package/dist/maps/controller.d.ts +57 -0
  269. package/dist/maps/controller.d.ts.map +1 -1
  270. package/dist/maps/controller.js +97 -18
  271. package/dist/maps/controller.js.map +1 -1
  272. package/dist/maps/gl/buckets.d.ts +5 -1
  273. package/dist/maps/gl/buckets.d.ts.map +1 -1
  274. package/dist/maps/gl/buckets.js +5 -2
  275. package/dist/maps/gl/buckets.js.map +1 -1
  276. package/dist/maps/gl/build-worker.d.ts +2 -0
  277. package/dist/maps/gl/build-worker.d.ts.map +1 -1
  278. package/dist/maps/gl/build-worker.js +1 -1
  279. package/dist/maps/gl/build-worker.js.map +1 -1
  280. package/dist/maps/gl/cover.d.ts +23 -4
  281. package/dist/maps/gl/cover.d.ts.map +1 -1
  282. package/dist/maps/gl/cover.js +61 -48
  283. package/dist/maps/gl/cover.js.map +1 -1
  284. package/dist/maps/gl/placement.d.ts +21 -8
  285. package/dist/maps/gl/placement.d.ts.map +1 -1
  286. package/dist/maps/gl/placement.js +133 -58
  287. package/dist/maps/gl/placement.js.map +1 -1
  288. package/dist/maps/gl/renderer.d.ts +36 -4
  289. package/dist/maps/gl/renderer.d.ts.map +1 -1
  290. package/dist/maps/gl/renderer.js +81 -24
  291. package/dist/maps/gl/renderer.js.map +1 -1
  292. package/dist/maps/gl/shaders.d.ts +18 -17
  293. package/dist/maps/gl/shaders.d.ts.map +1 -1
  294. package/dist/maps/gl/shaders.js +34 -32
  295. package/dist/maps/gl/shaders.js.map +1 -1
  296. package/dist/maps/gl/store.d.ts +10 -0
  297. package/dist/maps/gl/store.d.ts.map +1 -1
  298. package/dist/maps/gl/store.js +47 -4
  299. package/dist/maps/gl/store.js.map +1 -1
  300. package/dist/maps/gl/text.d.ts +153 -24
  301. package/dist/maps/gl/text.d.ts.map +1 -1
  302. package/dist/maps/gl/text.js +379 -63
  303. package/dist/maps/gl/text.js.map +1 -1
  304. package/dist/maps/gl/view.d.ts +293 -2
  305. package/dist/maps/gl/view.d.ts.map +1 -1
  306. package/dist/maps/gl/view.js +317 -82
  307. package/dist/maps/gl/view.js.map +1 -1
  308. package/dist/maps/icons.d.ts +32 -0
  309. package/dist/maps/icons.d.ts.map +1 -0
  310. package/dist/maps/icons.js +151 -0
  311. package/dist/maps/icons.js.map +1 -0
  312. package/dist/maps/index.d.ts +2 -0
  313. package/dist/maps/index.d.ts.map +1 -1
  314. package/dist/maps/index.js +2 -0
  315. package/dist/maps/index.js.map +1 -1
  316. package/dist/maps/labels.d.ts +56 -4
  317. package/dist/maps/labels.d.ts.map +1 -1
  318. package/dist/maps/labels.js +213 -46
  319. package/dist/maps/labels.js.map +1 -1
  320. package/dist/maps/node.d.ts +17 -0
  321. package/dist/maps/node.d.ts.map +1 -1
  322. package/dist/maps/node.js +64 -30
  323. package/dist/maps/node.js.map +1 -1
  324. package/dist/maps/proj.d.ts +48 -0
  325. package/dist/maps/proj.d.ts.map +1 -1
  326. package/dist/maps/proj.js +73 -0
  327. package/dist/maps/proj.js.map +1 -1
  328. package/dist/maps/sources.d.ts +5 -3
  329. package/dist/maps/sources.d.ts.map +1 -1
  330. package/dist/maps/sources.js +5 -3
  331. package/dist/maps/sources.js.map +1 -1
  332. package/dist/maps/style.d.ts +35 -0
  333. package/dist/maps/style.d.ts.map +1 -1
  334. package/dist/maps/style.js.map +1 -1
  335. package/dist/maps/styles.d.ts +12 -0
  336. package/dist/maps/styles.d.ts.map +1 -1
  337. package/dist/maps/styles.js +120 -6
  338. package/dist/maps/styles.js.map +1 -1
  339. package/dist/maps/tiles.d.ts +31 -11
  340. package/dist/maps/tiles.d.ts.map +1 -1
  341. package/dist/maps/tiles.js +61 -27
  342. package/dist/maps/tiles.js.map +1 -1
  343. package/dist/maps/types.d.ts +28 -4
  344. package/dist/maps/types.d.ts.map +1 -1
  345. package/dist/markdown/index.d.ts.map +1 -1
  346. package/dist/markdown/index.js +112 -43
  347. package/dist/markdown/index.js.map +1 -1
  348. package/dist/markdown/spans.d.ts.map +1 -1
  349. package/dist/markdown/spans.js +6 -0
  350. package/dist/markdown/spans.js.map +1 -1
  351. package/dist/qml/containers.d.ts.map +1 -1
  352. package/dist/qml/containers.js +6 -1
  353. package/dist/qml/containers.js.map +1 -1
  354. package/dist/qml/interaction.d.ts.map +1 -1
  355. package/dist/qml/interaction.js +38 -5
  356. package/dist/qml/interaction.js.map +1 -1
  357. package/dist/qml/layouts.d.ts.map +1 -1
  358. package/dist/qml/layouts.js +21 -6
  359. package/dist/qml/layouts.js.map +1 -1
  360. package/dist/qml/qtquick.d.ts.map +1 -1
  361. package/dist/qml/qtquick.js +9 -2
  362. package/dist/qml/qtquick.js.map +1 -1
  363. package/dist/qml/react.d.ts.map +1 -1
  364. package/dist/qml/react.js +9 -7
  365. package/dist/qml/react.js.map +1 -1
  366. package/dist/reorder/clock.d.ts +7 -0
  367. package/dist/reorder/clock.d.ts.map +1 -0
  368. package/dist/reorder/clock.js +26 -0
  369. package/dist/reorder/clock.js.map +1 -0
  370. package/dist/reorder/index.d.ts +25 -3
  371. package/dist/reorder/index.d.ts.map +1 -1
  372. package/dist/reorder/index.js +64 -19
  373. package/dist/reorder/index.js.map +1 -1
  374. package/dist/rich-text-editor/index.d.ts +0 -11
  375. package/dist/rich-text-editor/index.d.ts.map +1 -1
  376. package/dist/rich-text-editor/index.js +35 -1
  377. package/dist/rich-text-editor/index.js.map +1 -1
  378. package/dist/rich-text-editor/keymap.d.ts.map +1 -1
  379. package/dist/rich-text-editor/keymap.js +2 -1
  380. package/dist/rich-text-editor/keymap.js.map +1 -1
  381. package/dist/rich-text-editor/keys.d.ts +17 -6
  382. package/dist/rich-text-editor/keys.d.ts.map +1 -1
  383. package/dist/rich-text-editor/keys.js +135 -26
  384. package/dist/rich-text-editor/keys.js.map +1 -1
  385. package/dist/rich-text-editor/marks.d.ts +9 -0
  386. package/dist/rich-text-editor/marks.d.ts.map +1 -0
  387. package/dist/rich-text-editor/marks.js +83 -0
  388. package/dist/rich-text-editor/marks.js.map +1 -0
  389. package/dist/rich-text-editor/render.d.ts.map +1 -1
  390. package/dist/rich-text-editor/render.js +28 -10
  391. package/dist/rich-text-editor/render.js.map +1 -1
  392. package/dist/rich-text-editor/toolbar.d.ts.map +1 -1
  393. package/dist/rich-text-editor/toolbar.js +1 -1
  394. package/dist/rich-text-editor/toolbar.js.map +1 -1
  395. package/dist/rich-text-editor/virtual.d.ts.map +1 -1
  396. package/dist/rich-text-editor/virtual.js +17 -0
  397. package/dist/rich-text-editor/virtual.js.map +1 -1
  398. package/dist/richtext/node.d.ts +46 -2
  399. package/dist/richtext/node.d.ts.map +1 -1
  400. package/dist/richtext/node.js +187 -4
  401. package/dist/richtext/node.js.map +1 -1
  402. package/dist/richtext/runs.d.ts +13 -8
  403. package/dist/richtext/runs.d.ts.map +1 -1
  404. package/dist/richtext/runs.js +18 -8
  405. package/dist/richtext/runs.js.map +1 -1
  406. package/dist/table/index.d.ts.map +1 -1
  407. package/dist/table/index.js +23 -0
  408. package/dist/table/index.js.map +1 -1
  409. package/dist/table/rows.d.ts +3 -2
  410. package/dist/table/rows.d.ts.map +1 -1
  411. package/dist/table/rows.js +20 -6
  412. package/dist/table/rows.js.map +1 -1
  413. package/dist/terminal/index.d.ts.map +1 -1
  414. package/dist/terminal/index.js +4 -0
  415. package/dist/terminal/index.js.map +1 -1
  416. package/dist/terminal/vt/pty.d.ts +13 -2
  417. package/dist/terminal/vt/pty.d.ts.map +1 -1
  418. package/dist/terminal/vt/pty.js +18 -3
  419. package/dist/terminal/vt/pty.js.map +1 -1
  420. package/dist/terminal-output/index.d.ts.map +1 -1
  421. package/dist/terminal-output/index.js +6 -1
  422. package/dist/terminal-output/index.js.map +1 -1
  423. package/dist/three/canvas.d.ts.map +1 -1
  424. package/dist/three/canvas.js +85 -7
  425. package/dist/three/canvas.js.map +1 -1
  426. package/dist/three/events.d.ts +22 -4
  427. package/dist/three/events.d.ts.map +1 -1
  428. package/dist/three/events.js +34 -4
  429. package/dist/three/events.js.map +1 -1
  430. package/dist/tree/index.d.ts.map +1 -1
  431. package/dist/tree/index.js +17 -0
  432. package/dist/tree/index.js.map +1 -1
  433. package/package.json +42 -33
  434. package/src/charts/node.ts +62 -26
  435. package/src/charts/render.ts +120 -30
  436. package/src/code/index.ts +3 -1
  437. package/src/code-editor/completion.ts +3 -2
  438. package/src/code-editor/index.ts +19 -0
  439. package/src/code-editor/node.ts +1574 -184
  440. package/src/code-language/languages/glsl.ts +12 -2
  441. package/src/code-language/languages/javascript.ts +21 -4
  442. package/src/code-language/languages/json.ts +12 -2
  443. package/src/code-language/languages/shell.ts +12 -2
  444. package/src/code-language/languages/sql.ts +22 -2
  445. package/src/code-language/stream.ts +257 -17
  446. package/src/code-language/types.ts +5 -4
  447. package/src/codeblock/index.ts +20 -3
  448. package/src/flow/draw.ts +167 -41
  449. package/src/flow/gl/color.ts +85 -0
  450. package/src/flow/gl/index.ts +342 -0
  451. package/src/flow/gl/pack.ts +585 -0
  452. package/src/flow/gl/renderer.ts +679 -0
  453. package/src/flow/gl/shaders.ts +371 -0
  454. package/src/flow/gl/text.ts +1295 -0
  455. package/src/flow/index.ts +794 -67
  456. package/src/flow/node.ts +2496 -1256
  457. package/src/flow/paint.ts +511 -0
  458. package/src/flow/paths.ts +80 -15
  459. package/src/flow/scene.ts +2199 -0
  460. package/src/flow/types.ts +113 -1
  461. package/src/html/controls.ts +73 -2
  462. package/src/html/css/calc.ts +385 -0
  463. package/src/html/css/cascade.ts +1403 -62
  464. package/src/html/css/color.ts +755 -0
  465. package/src/html/css/content.ts +417 -0
  466. package/src/html/css/counter-styles.ts +973 -0
  467. package/src/html/css/decode.ts +130 -0
  468. package/src/html/css/parse.ts +1514 -160
  469. package/src/html/css/style.ts +4102 -222
  470. package/src/html/css/ua.ts +58 -12
  471. package/src/html/css/values.ts +150 -50
  472. package/src/html/css/vars.ts +348 -0
  473. package/src/html/dom.ts +284 -17
  474. package/src/html/fonts.ts +641 -0
  475. package/src/html/gif.ts +233 -0
  476. package/src/html/index.ts +180 -20
  477. package/src/html/layout/block.ts +3456 -230
  478. package/src/html/layout/boxes.ts +2100 -190
  479. package/src/html/layout/cache.ts +289 -0
  480. package/src/html/layout/collapse.ts +317 -0
  481. package/src/html/layout/css-grid.ts +1063 -0
  482. package/src/html/layout/flex.ts +1115 -106
  483. package/src/html/layout/floats.ts +128 -14
  484. package/src/html/layout/grid-lines.ts +141 -0
  485. package/src/html/layout/grid.ts +181 -0
  486. package/src/html/layout/inline.ts +3943 -192
  487. package/src/html/layout/shaping.ts +140 -0
  488. package/src/html/layout/table.ts +696 -186
  489. package/src/html/layout/tracks.ts +437 -0
  490. package/src/html/node.ts +1481 -118
  491. package/src/html/paint.ts +4293 -169
  492. package/src/html/resources.ts +161 -50
  493. package/src/html/surfaces.ts +81 -0
  494. package/src/html/svg.ts +493 -0
  495. package/src/html/url.ts +86 -0
  496. package/src/index.ts +2 -0
  497. package/src/internal/collate.ts +12 -0
  498. package/src/internal/markdown/ast.ts +11 -0
  499. package/src/internal/markdown/parse.ts +154 -11
  500. package/src/internal/prewarm.ts +45 -0
  501. package/src/internal/sdf.ts +227 -0
  502. package/src/internal/splice.ts +25 -0
  503. package/src/internal/window.ts +36 -5
  504. package/src/maps/anchors.ts +307 -1
  505. package/src/maps/controller.ts +116 -31
  506. package/src/maps/gl/buckets.ts +5 -1
  507. package/src/maps/gl/build-worker.ts +13 -2
  508. package/src/maps/gl/cover.ts +79 -44
  509. package/src/maps/gl/placement.ts +221 -69
  510. package/src/maps/gl/renderer.ts +104 -20
  511. package/src/maps/gl/shaders.ts +35 -32
  512. package/src/maps/gl/store.ts +66 -17
  513. package/src/maps/gl/text.ts +444 -71
  514. package/src/maps/gl/view.ts +361 -96
  515. package/src/maps/icons.ts +183 -0
  516. package/src/maps/index.ts +4 -0
  517. package/src/maps/labels.ts +269 -49
  518. package/src/maps/node.ts +82 -49
  519. package/src/maps/proj.ts +87 -0
  520. package/src/maps/sources.ts +5 -3
  521. package/src/maps/style.ts +32 -0
  522. package/src/maps/styles.ts +215 -4
  523. package/src/maps/tiles.ts +64 -31
  524. package/src/maps/types.ts +28 -4
  525. package/src/markdown/index.ts +149 -67
  526. package/src/markdown/spans.ts +5 -0
  527. package/src/qml/containers.tsx +6 -1
  528. package/src/qml/interaction.tsx +42 -5
  529. package/src/qml/layouts.tsx +21 -6
  530. package/src/qml/qtquick.tsx +9 -2
  531. package/src/qml/react.tsx +7 -5
  532. package/src/reorder/clock.ts +27 -0
  533. package/src/reorder/index.ts +100 -27
  534. package/src/rich-text-editor/index.ts +34 -1
  535. package/src/rich-text-editor/keymap.ts +1 -1
  536. package/src/rich-text-editor/keys.ts +135 -26
  537. package/src/rich-text-editor/marks.ts +101 -0
  538. package/src/rich-text-editor/render.ts +49 -12
  539. package/src/rich-text-editor/toolbar.ts +1 -1
  540. package/src/rich-text-editor/virtual.ts +25 -0
  541. package/src/richtext/node.ts +235 -14
  542. package/src/richtext/runs.ts +23 -12
  543. package/src/table/index.ts +29 -0
  544. package/src/table/rows.ts +18 -8
  545. package/src/terminal/index.ts +4 -0
  546. package/src/terminal/vt/pty.ts +16 -2
  547. package/src/terminal-output/index.ts +6 -1
  548. package/src/three/canvas.ts +102 -8
  549. package/src/three/events.ts +49 -9
  550. package/src/tree/index.ts +19 -0
@@ -181,31 +181,168 @@ function indentOf(line: string): number {
181
181
 
182
182
  export function parse(source: string, options: ParseOptions = {}): Document {
183
183
  const partial = options.partial !== false;
184
+ const isComponent = options.isComponent ?? NO_COMPONENTS;
185
+ const expressions = options.expressions === true;
184
186
  const normalized = source.replace(/\r\n?/g, '\n');
185
187
  const lines = normalized.split('\n').map(expandLeadingTabs);
188
+ const previous = options.previous;
189
+ const was = previous ? resumable.get(previous) : undefined;
190
+ // Not with components: an open tag looks for its close to the end of the
191
+ // document (`componentCloseLine`), so a close added anywhere below can
192
+ // change what it is, and the block before an edit is no longer settled.
193
+ if (
194
+ previous &&
195
+ was &&
196
+ was.partial === partial &&
197
+ was.expressions === expressions &&
198
+ isComponent === NO_COMPONENTS &&
199
+ was.isComponent === NO_COMPONENTS
200
+ ) {
201
+ return resume(previous, was, lines);
202
+ }
186
203
  const blocks: BlockNode[] = [];
187
204
  const ranges: Array<[number, number]> = [];
188
- parseBlocks(
205
+ const blanks = new Uint8Array(lines.length);
206
+ parseBlocks(lines, partial, blocks, ranges, isComponent, expressions, {
207
+ from: 0,
208
+ blanks,
209
+ });
210
+ return remember(
211
+ { blocks, raws: ranges.map(([a, b]) => lines.slice(a, b).join('\n')) },
212
+ { lines, ranges, blanks, partial, isComponent, expressions },
213
+ );
214
+ }
215
+
216
+ // --- resuming --------------------------------------------------------------
217
+
218
+ /**
219
+ * What a parse leaves for the next parse of the same document to start from
220
+ * (`ParseOptions.previous`).
221
+ *
222
+ * The block loop carries one thing from a block to the next, the paragraph
223
+ * it is gathering, and it looks only forwards: a block's extent is decided
224
+ * by the lines up to the first line of the block after it. So `blanks`
225
+ * marks the lines where the loop stood on a blank line at the top level with
226
+ * no paragraph open. Two parses standing on such a line, with the same lines
227
+ * from there to the end, produce the same blocks from there on. That is the
228
+ * point where an edit's re-parse can stop and take the rest from before.
229
+ */
230
+ interface Resumable {
231
+ lines: string[];
232
+ /** each top-level block's [start, endExcl) line range */
233
+ ranges: Array<[number, number]>;
234
+ /** 1 on each line where the top-level loop stood blank with no paragraph */
235
+ blanks: Uint8Array;
236
+ partial: boolean;
237
+ isComponent: (name: string) => boolean;
238
+ expressions: boolean;
239
+ }
240
+
241
+ /** Kept beside the documents rather than in them, so a Document stays the
242
+ * plain data every caller and test compares. */
243
+ const resumable = new WeakMap<Document, Resumable>();
244
+
245
+ function remember(doc: Document, state: Resumable): Document {
246
+ resumable.set(doc, state);
247
+ return doc;
248
+ }
249
+
250
+ /**
251
+ * Parse `lines` as an edit of `previous`: from one block before the first
252
+ * line that changed, until the loop stands where the previous parse stood
253
+ * in the lines the edit left alone — or to the end, when it never does (an
254
+ * unclosed fence swallows the rest of a document either way).
255
+ */
256
+ function resume(previous: Document, was: Resumable, lines: string[]): Document {
257
+ const old = was.lines;
258
+ const oldN = old.length;
259
+ const n = lines.length;
260
+ const shortest = Math.min(oldN, n);
261
+ let first = 0;
262
+ while (first < shortest && old[first] === lines[first]) first += 1;
263
+ if (first === oldN && first === n) return previous;
264
+ // lines at the end the edit did not touch, never counting the prefix twice
265
+ let same = 0;
266
+ while (
267
+ same < shortest - first &&
268
+ old[oldN - 1 - same] === lines[n - 1 - same]
269
+ ) {
270
+ same += 1;
271
+ }
272
+ const shift = n - oldN;
273
+ const suffix = n - same;
274
+
275
+ // The first block that reaches the change, and the one before it: a
276
+ // block's extent is decided by the lines up to the next block's first —
277
+ // a list looks past blank lines to see whether it goes on — so the block
278
+ // before the first one touched cannot have depended on the change.
279
+ const { ranges } = was;
280
+ let lo = 0;
281
+ let hi = ranges.length;
282
+ while (lo < hi) {
283
+ const mid = (lo + hi) >> 1;
284
+ if (ranges[mid][1] <= first) lo = mid + 1;
285
+ else hi = mid;
286
+ }
287
+ const kept = Math.max(0, lo - 1);
288
+ const from = kept === 0 ? 0 : ranges[kept][0];
289
+
290
+ const blanks = new Uint8Array(n);
291
+ blanks.set(was.blanks.subarray(0, from));
292
+ const blocks: BlockNode[] = previous.blocks.slice(0, kept);
293
+ const raws = previous.raws.slice(0, kept);
294
+ const next: Array<[number, number]> = ranges.slice(0, kept);
295
+ const fresh: Array<[number, number]> = [];
296
+ const stop = parseBlocks(
189
297
  lines,
190
- partial,
298
+ was.partial,
191
299
  blocks,
192
- ranges,
193
- options.isComponent ?? NO_COMPONENTS,
194
- options.expressions === true,
300
+ fresh,
301
+ was.isComponent,
302
+ was.expressions,
303
+ {
304
+ from,
305
+ blanks,
306
+ resync: (i) => i >= suffix && was.blanks[i - shift] === 1,
307
+ },
195
308
  );
196
- return {
197
- blocks,
198
- raws: ranges.map(([a, b]) => lines.slice(a, b).join('\n')),
199
- };
309
+ for (const [a, b] of fresh) {
310
+ raws.push(lines.slice(a, b).join('\n'));
311
+ next.push([a, b]);
312
+ }
313
+ if (stop < n) {
314
+ // the previous parse from the same place over the same lines: its
315
+ // blocks, where they now are
316
+ const at = stop - shift;
317
+ blanks.set(was.blanks.subarray(at), stop);
318
+ let j = ranges.length;
319
+ while (j > 0 && ranges[j - 1][0] >= at) j -= 1;
320
+ for (; j < ranges.length; j += 1) {
321
+ blocks.push(previous.blocks[j]);
322
+ raws.push(previous.raws[j]);
323
+ next.push([ranges[j][0] + shift, ranges[j][1] + shift]);
324
+ }
325
+ }
326
+ return remember({ blocks, raws }, { ...was, lines, ranges: next, blanks });
200
327
  }
201
328
 
202
329
  // --- block layer -----------------------------------------------------------
203
330
 
331
+ /** The top-level call's extra: where to start, where to record the blank
332
+ * lines it stands on, and when to stop (`resume`). */
333
+ interface TopLevel {
334
+ from: number;
335
+ blanks: Uint8Array;
336
+ resync?: (line: number) => boolean;
337
+ }
338
+
204
339
  /**
205
340
  * Parse a run of lines into blocks. `tailOpen` says the end of `lines` is
206
341
  * the live end of a streaming document — the license for every "complete it
207
342
  * anyway" rule. `ranges`, when given, receives each block's [start, endExcl)
208
343
  * line range (only the top-level call wants them, for the streaming cache).
344
+ * Returns the line it stopped at: the end, or where `top.resync` said the
345
+ * rest would come out as it did before.
209
346
  */
210
347
  function parseBlocks(
211
348
  lines: string[],
@@ -214,8 +351,9 @@ function parseBlocks(
214
351
  ranges?: Array<[number, number]>,
215
352
  isComponent: (name: string) => boolean = NO_COMPONENTS,
216
353
  expressions = false,
217
- ): void {
218
- let i = 0;
354
+ top?: TopLevel,
355
+ ): number {
356
+ let i = top?.from ?? 0;
219
357
  const n = lines.length;
220
358
 
221
359
  let paraStart = -1;
@@ -245,6 +383,10 @@ function parseBlocks(
245
383
 
246
384
  if (RE_BLANK.test(line)) {
247
385
  flushPara(i);
386
+ if (top) {
387
+ if (top.resync?.(i)) return i;
388
+ top.blanks[i] = 1;
389
+ }
248
390
  i += 1;
249
391
  continue;
250
392
  }
@@ -571,6 +713,7 @@ function parseBlocks(
571
713
  }
572
714
 
573
715
  flushPara(n);
716
+ return n;
574
717
  }
575
718
 
576
719
  // --- lists -----------------------------------------------------------------
@@ -0,0 +1,45 @@
1
+ // A font family, warmed before the first layout sets text in it.
2
+ import { useMemo } from 'react';
3
+ import { useApp } from 'react-x11';
4
+
5
+ /** The one method this needs of `app.fonts`, which ntk's FontManager has
6
+ * from the release that added it, and other font managers may not. */
7
+ interface PrewarmingFonts {
8
+ prewarm?: (family: string) => void;
9
+ }
10
+
11
+ /**
12
+ * Start matching `family`'s faces now, off the event loop, so that the first
13
+ * layout setting text in it takes the answer instead of stalling on the
14
+ * system's font matcher — ntk's `FontManager#prewarm`. fontconfig answers in
15
+ * 20–40 ms on a Linux desktop and in 80–150 on XQuartz, and nothing warms a
16
+ * family but sans-serif until a layout asks for it.
17
+ *
18
+ * Called while rendering, as React's own resource hints are: a component
19
+ * renders ahead of the frame that lays it out, and a long document's render
20
+ * is hundreds of milliseconds of head start that an effect would give away.
21
+ * Once per family; nothing where the app's fonts have nothing to look up
22
+ * (fonts in memory, a native text engine) or predate the method.
23
+ */
24
+ export function useFontPrewarm(family: string | null | undefined): void {
25
+ const fonts = (useApp() as { fonts?: PrewarmingFonts } | null)?.fonts;
26
+ useMemo(() => {
27
+ if (family) fonts?.prewarm?.(family);
28
+ }, [fonts, family]);
29
+ }
30
+
31
+ /** The font family a style names, read the way core flattens one — the last
32
+ * entry of an array that names it wins — or `fallback`. */
33
+ export function styleFamily(style: unknown, fallback: string): string {
34
+ let family = fallback;
35
+ const visit = (entry: unknown): void => {
36
+ if (Array.isArray(entry)) {
37
+ for (const e of entry) visit(e);
38
+ } else if (entry && typeof entry === 'object') {
39
+ const named = (entry as { fontFamily?: unknown }).fontFamily;
40
+ if (typeof named === 'string') family = named;
41
+ }
42
+ };
43
+ visit(style);
44
+ return family;
45
+ }
@@ -0,0 +1,227 @@
1
+ // A label's raster as a signed distance field: what lets one raster serve a
2
+ // name at every size a zoom passes through, and a halo of any width. Under
3
+ // the GL labels of both `<Map>` (`src/maps/gl/text.ts`) and `<Flow>`
4
+ // (`src/flow/gl/text.ts`), which is why it is here rather than in either.
5
+ //
6
+ // The text engine sets a string as coverage — alpha, antialiased — at one
7
+ // base size. Each texel here becomes its distance to the glyphs' edge,
8
+ // encoded in a byte so that `SDF_EDGE` is the edge itself, more is inside
9
+ // and less is outside:
10
+ //
11
+ // byte = 255 · (1 − d / radius − SDF_CUTOFF), d > 0 outside
12
+ //
13
+ // so a field reaches `radius · (1 − SDF_CUTOFF)` texels past the glyphs
14
+ // before it saturates at 0 — the room a halo has to grow into — and
15
+ // `radius · SDF_CUTOFF` into them.
16
+ //
17
+ // The distance is the exact Euclidean one, started at the edge by what the
18
+ // coverage says: an antialiased texel half covered sits on the edge, one a
19
+ // quarter covered a quarter of a texel outside it. That sub-texel start is
20
+ // what keeps a field set at 16 pixels from drawing a lumpy stroke at 40.
21
+ //
22
+ // **Only where it can change a byte.** A field is set the first time its
23
+ // string is drawn, so its cost is how late a label appears. Outside the
24
+ // glyphs the distance is Felzenszwalb and Huttenlocher's linear-time
25
+ // transform — but only over the window a field reaches round the ink, the
26
+ // rows that hold ink first and then the window's columns, since past the
27
+ // reach every byte is 0 and every source is inside it. Inside, a field
28
+ // saturates `radius · SDF_CUTOFF` texels in (1.5 at Flow's margin, 2.25 at
29
+ // a map's), so the nearest texel less than half covered is found by
30
+ // searching the few rings round each texel inside, not by a second
31
+ // transform over the whole raster. Byte for byte what the two whole
32
+ // transforms gave, at half the cost: measured over DirectWrite's coverage
33
+ // of 520 labels, 262 → 140 µs a field at Flow's margin and 626 → 311 at a
34
+ // map's.
35
+
36
+ /** The fraction of the byte range spent inside the glyphs. */
37
+ export const SDF_CUTOFF = 0.25;
38
+
39
+ /** The byte value of the glyphs' edge, as a fraction: `1 − SDF_CUTOFF`. */
40
+ export const SDF_EDGE = 1 - SDF_CUTOFF;
41
+
42
+ /**
43
+ * Device pixels outside a field's outline that its ink's edge is drawn. A
44
+ * text engine darkens stems at small sizes; a field thresholded at half
45
+ * coverage gives that back, and a string drawn from one looks a weight
46
+ * lighter than the same string set. Both GL label shaders draw it.
47
+ */
48
+ export const SDF_INK_BIAS_PX = 0.15;
49
+
50
+ /** "No edge in reach": far past any raster's squared diagonal, and small
51
+ * enough that `FAR + q²` is still exact in a double, so two of them cross
52
+ * where two parabolas of one height do. */
53
+ const FAR = 1e10;
54
+
55
+ /**
56
+ * Each coverage byte's squared distance to the edge *inside* its own
57
+ * texel: (a − ½)² where more than half covered, 0 where not — a texel less
58
+ * than half covered is outside, where an inside distance ends — and FAR
59
+ * where whole.
60
+ */
61
+ const INSIDE = new Float64Array(256);
62
+ for (let a8 = 1; a8 < 255; a8++) {
63
+ const d = 0.5 - a8 / 255;
64
+ INSIDE[a8] = d < 0 ? d * d : 0;
65
+ }
66
+ INSIDE[255] = FAR;
67
+
68
+ /** Scratch, grown to the largest raster seen and reused. */
69
+ let outer = new Float64Array(0);
70
+ let f = new Float64Array(0);
71
+ let g = new Float64Array(0);
72
+ let z = new Float64Array(0);
73
+ let v = new Int32Array(0);
74
+
75
+ function grow(texels: number, line: number): void {
76
+ if (outer.length < texels) outer = new Float64Array(texels);
77
+ if (f.length < line) {
78
+ f = new Float64Array(line);
79
+ g = new Float64Array(line);
80
+ z = new Float64Array(line + 1);
81
+ v = new Int32Array(line);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * The squared distance transform of `length` values of `grid` from
87
+ * `offset`, `stride` apart, in place: each becomes the least
88
+ * `grid[r] + (q − r)²` — the lower envelope of parabolas rooted at every
89
+ * texel. `g` holds each parabola's `grid[r] + r²`, so where two cross is
90
+ * one division.
91
+ */
92
+ function transform1d(
93
+ grid: Float64Array,
94
+ offset: number,
95
+ stride: number,
96
+ length: number,
97
+ ): void {
98
+ let k = 0;
99
+ v[0] = 0;
100
+ z[0] = -Infinity;
101
+ z[1] = Infinity;
102
+ f[0] = grid[offset];
103
+ g[0] = f[0];
104
+ for (let q = 1, at = offset + stride; q < length; q++, at += stride) {
105
+ const fq = grid[at];
106
+ f[q] = fq;
107
+ const gq = fq + q * q;
108
+ g[q] = gq;
109
+ let s: number;
110
+ for (;;) {
111
+ const r = v[k];
112
+ s = (gq - g[r]) / (2 * (q - r));
113
+ if (s > z[k] || k === 0) break;
114
+ k--;
115
+ }
116
+ k++;
117
+ v[k] = q;
118
+ z[k] = s;
119
+ z[k + 1] = Infinity;
120
+ }
121
+ k = 0;
122
+ for (let q = 0, at = offset; q < length; q++, at += stride) {
123
+ while (z[k + 1] < q) k++;
124
+ const r = v[k];
125
+ const d = q - r;
126
+ grid[at] = f[r] + d * d;
127
+ }
128
+ }
129
+
130
+ /**
131
+ * The field of a `width` × `height` raster whose coverage is `alpha`
132
+ * (0-255), read every `step` bytes from `start` — so an RGBA readback is
133
+ * read in place, `step` 4 and `start` 3, and an engine's own coverage with
134
+ * `step` 1 and `start` 0. One byte a texel, see the top of this file for
135
+ * the encoding.
136
+ */
137
+ export function distanceField(
138
+ alpha: Uint8Array,
139
+ width: number,
140
+ height: number,
141
+ radius: number,
142
+ step = 4,
143
+ start = 3,
144
+ ): Uint8Array {
145
+ const texels = width * height;
146
+ grow(texels, Math.max(width, height));
147
+ // Zeroed: a byte nothing below writes is as far outside as a field sees.
148
+ const out = new Uint8Array(texels);
149
+ let minX = width;
150
+ let maxX = -1;
151
+ let minY = height;
152
+ let maxY = -1;
153
+ for (let y = 0, i = 0, a = start; y < height; y++) {
154
+ for (let x = 0; x < width; x++, i++, a += step) {
155
+ const a8 = alpha[a];
156
+ if (a8 === 0) {
157
+ outer[i] = FAR;
158
+ continue;
159
+ }
160
+ if (x < minX) minX = x;
161
+ if (x > maxX) maxX = x;
162
+ if (y < minY) minY = y;
163
+ if (y > maxY) maxY = y;
164
+ if (a8 === 255) {
165
+ outer[i] = 0;
166
+ continue;
167
+ }
168
+ // Partly covered: on the edge, off it by how far from half covered.
169
+ const d = 0.5 - a8 / 255;
170
+ outer[i] = d > 0 ? d * d : 0;
171
+ }
172
+ }
173
+ if (maxX < 0) return out;
174
+
175
+ // Outside: the window the field reaches round the ink. Every source is
176
+ // in it, so what the transform computes there is exact, and past it every
177
+ // byte is 0. The rows with ink first — every source is on one — then
178
+ // every column of the window.
179
+ const reach = Math.ceil(radius * (1 - SDF_CUTOFF)) + 1;
180
+ const x0 = Math.max(0, minX - reach);
181
+ const x1 = Math.min(width - 1, maxX + reach);
182
+ const y0 = Math.max(0, minY - reach);
183
+ const y1 = Math.min(height - 1, maxY + reach);
184
+ for (let y = minY; y <= maxY; y++) {
185
+ transform1d(outer, y * width + x0, 1, x1 - x0 + 1);
186
+ }
187
+ for (let x = x0; x <= x1; x++) {
188
+ transform1d(outer, y0 * width + x, width, y1 - y0 + 1);
189
+ }
190
+
191
+ // Inside, the field saturates this many rings in.
192
+ const deep = Math.ceil(radius * SDF_CUTOFF);
193
+ for (let y = y0; y <= y1; y++) {
194
+ for (let x = x0, i = y * width + x0; x <= x1; x++, i++) {
195
+ // Outside the ink, or in it: never both.
196
+ const o = outer[i];
197
+ let d: number;
198
+ if (o > 0) {
199
+ d = Math.sqrt(o);
200
+ } else {
201
+ // The least (a − ½)² + distance² over the texels round it, ring by
202
+ // ring, until no ring further out could be nearer — or the field
203
+ // has saturated, where the exact answer and this one are both 255.
204
+ let best = INSIDE[alpha[start + i * step]];
205
+ for (let k = 1; k <= deep && best > k * k; k++) {
206
+ for (let yy = y - k; yy <= y + k; yy++) {
207
+ if (yy < 0 || yy >= height) continue;
208
+ const dy2 = (yy - y) * (yy - y);
209
+ // a ring's top and bottom rows whole, its sides two texels
210
+ const across = yy === y - k || yy === y + k ? 1 : 2 * k;
211
+ for (let xx = x - k; xx <= x + k; xx += across) {
212
+ if (xx < 0 || xx >= width) continue;
213
+ const dx = xx - x;
214
+ const m =
215
+ INSIDE[alpha[start + (yy * width + xx) * step]] + dx * dx + dy2;
216
+ if (m < best) best = m;
217
+ }
218
+ }
219
+ }
220
+ d = -Math.sqrt(best);
221
+ }
222
+ const value = Math.round(255 - 255 * (d / radius + SDF_CUTOFF));
223
+ out[i] = value < 0 ? 0 : value > 255 ? 255 : value;
224
+ }
225
+ }
226
+ return out;
227
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `target.splice(from, removed, ...items)`, for any number of items.
3
+ *
4
+ * A spread argument list lives on the stack, and somewhere past a hundred
5
+ * thousand items it throws `RangeError: Maximum call stack size exceeded` —
6
+ * a pasted log, or a file replaced whole, is that many lines. Past a few
7
+ * thousand the array is rebuilt in place instead: whoever holds `target`
8
+ * keeps holding it, which is the whole reason it is spliced rather than
9
+ * replaced.
10
+ */
11
+ export function spliceAll<T>(
12
+ target: T[],
13
+ from: number,
14
+ removed: number,
15
+ items: readonly T[],
16
+ ): void {
17
+ if (items.length <= 4096) {
18
+ target.splice(from, removed, ...items);
19
+ return;
20
+ }
21
+ const tail = target.slice(from + removed);
22
+ target.length = from;
23
+ for (let i = 0; i < items.length; i++) target.push(items[i]);
24
+ for (let i = 0; i < tail.length; i++) target.push(tail[i]);
25
+ }
@@ -30,7 +30,8 @@
30
30
  // forces them out, trailing side first — a direction reversal lands on
31
31
  // rows still mounted instead of rebuilding them. The budget caps what a
32
32
  // render can be asked to carry: the on-screen slice plus `prefetch` rows
33
- // each side.
33
+ // each side — at any speed, which is why a row is measured on its way
34
+ // out when nothing has measured it yet.
34
35
  // - **Skeletons.** A scroll that outruns everything — a thumb dragged
35
36
  // across the list, a flick past the band — floods the window with rows
36
37
  // no single render can build in time. Those render as *skeletons*: the
@@ -164,6 +165,18 @@ export interface VirtualWindowInputs {
164
165
  * settled. `BURST_BUDGET` / `SETTLE_BUDGET` are the defaults. */
165
166
  burstBudget: number;
166
167
  settleBudget: number;
168
+ /**
169
+ * Record the height the drawn row `id`, at `index`, is laid out at in the
170
+ * index, now; answer whether the index has a real height for it after.
171
+ * The trim asks before it drops a row the measure tick has not reached
172
+ * (see the budget below), during render — so no nudge and no re-render:
173
+ * the row is still laid out at exactly that height, and nothing on screen
174
+ * moves until the spacer takes its place. `false` for a row with no
175
+ * honest measurement to give, which keeps it mounted. `viewport` is the
176
+ * event-fresh one (`viewRef`), for a component whose rows are laid out
177
+ * against it.
178
+ */
179
+ measure?: (id: RowKey, index: number, viewport: VirtualViewport) => boolean;
167
180
  }
168
181
 
169
182
  export interface VirtualWindow {
@@ -370,6 +383,7 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
370
383
  threshold,
371
384
  burstBudget,
372
385
  settleBudget,
386
+ measure,
373
387
  } = inputs;
374
388
  const count = rows.length;
375
389
 
@@ -448,15 +462,32 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
448
462
  // row laid out taller than the index believes contributes its real
449
463
  // height while mounted and its guessed one once dropped, so cutting
450
464
  // it silently shrinks the content above the viewport and the view
451
- // yanks up by the difference with no debt left to put it right. Held
452
- // a render or two longer, it gets measured, and the next trim takes
453
- // it cleanly.
465
+ // yanks up by the difference with no debt left to put it right.
466
+ //
467
+ // So a row the index has no number for is measured *here*, where it
468
+ // is still laid out (`measure`): once the index holds the height it
469
+ // is drawn at, the spacer that replaces it is exactly as tall, and it
470
+ // goes like any other. Waiting for the measure tick instead is only
471
+ // safe while the tick runs — and a flick defers every measurement to
472
+ // the settle, so a long one downward trimmed nothing at all and the
473
+ // window grew by every row it passed: 1,250 rows mounted four seconds
474
+ // into a trackpad fling, each frame laying all of them out. A row the
475
+ // last render did not build in full needs nothing: a skeleton is
476
+ // drawn at the index's height, and a row never drawn is not in the
477
+ // layout at all. What cannot be measured — a row not laid out yet, or
478
+ // laid out against a grid it is about to leave — is held a render or
479
+ // two longer, as before.
454
480
  const budget = coreLast - coreFirst + 2 * prefetch;
455
481
  let excess = last - first - budget;
456
482
  if (excess > 0) {
483
+ const known = (i: number): boolean =>
484
+ exact ||
485
+ heights.isMeasured(i) ||
486
+ !real.current.has(rows[i].id) ||
487
+ measure?.(rows[i].id, i, viewRef.current) === true;
457
488
  const cutAbove = (want: number): number => {
458
489
  let k = 0;
459
- while (k < want && (exact || heights.isMeasured(first + k))) k++;
490
+ while (k < want && known(first + k)) k++;
460
491
  return k;
461
492
  };
462
493
  const aboveExtra = coreFirst - first;