vastgrid 0.1.1 → 0.2.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 (312) hide show
  1. package/README.md +175 -13
  2. package/dist/canvas/geometry.d.ts +92 -0
  3. package/dist/canvas/geometry.d.ts.map +1 -0
  4. package/dist/canvas/geometry.js +197 -0
  5. package/dist/canvas/geometry.js.map +1 -0
  6. package/dist/canvas/grid-canvas.d.ts +161 -0
  7. package/dist/canvas/grid-canvas.d.ts.map +1 -0
  8. package/dist/canvas/grid-canvas.js +1146 -0
  9. package/dist/canvas/grid-canvas.js.map +1 -0
  10. package/dist/canvas/hooks.d.ts +61 -0
  11. package/dist/canvas/hooks.d.ts.map +1 -0
  12. package/dist/canvas/hooks.js +2 -0
  13. package/dist/canvas/hooks.js.map +1 -0
  14. package/dist/canvas/keys.d.ts +26 -0
  15. package/dist/canvas/keys.d.ts.map +1 -0
  16. package/dist/canvas/keys.js +133 -0
  17. package/dist/canvas/keys.js.map +1 -0
  18. package/dist/canvas/layout.d.ts +26 -0
  19. package/dist/canvas/layout.d.ts.map +1 -0
  20. package/dist/canvas/layout.js +73 -0
  21. package/dist/canvas/layout.js.map +1 -0
  22. package/dist/canvas/scroll.d.ts +31 -0
  23. package/dist/canvas/scroll.d.ts.map +1 -0
  24. package/dist/canvas/scroll.js +111 -0
  25. package/dist/canvas/scroll.js.map +1 -0
  26. package/dist/canvas/text.d.ts +23 -0
  27. package/dist/canvas/text.d.ts.map +1 -0
  28. package/dist/canvas/text.js +142 -0
  29. package/dist/canvas/text.js.map +1 -0
  30. package/dist/{theme.d.ts → canvas/theme.d.ts} +8 -0
  31. package/dist/canvas/theme.d.ts.map +1 -0
  32. package/dist/canvas/theme.js +62 -0
  33. package/dist/canvas/theme.js.map +1 -0
  34. package/dist/core/cache.d.ts +48 -0
  35. package/dist/core/cache.d.ts.map +1 -0
  36. package/dist/core/cache.js +222 -0
  37. package/dist/core/cache.js.map +1 -0
  38. package/dist/core/checked.d.ts +20 -0
  39. package/dist/core/checked.d.ts.map +1 -0
  40. package/dist/core/checked.js +61 -0
  41. package/dist/core/checked.js.map +1 -0
  42. package/dist/core/client.d.ts +33 -0
  43. package/dist/core/client.d.ts.map +1 -0
  44. package/dist/core/client.js +103 -0
  45. package/dist/core/client.js.map +1 -0
  46. package/dist/core/conditions.d.ts +48 -0
  47. package/dist/core/conditions.d.ts.map +1 -0
  48. package/dist/core/conditions.js +105 -0
  49. package/dist/core/conditions.js.map +1 -0
  50. package/dist/core/evaluate.d.ts +20 -0
  51. package/dist/core/evaluate.d.ts.map +1 -0
  52. package/dist/core/evaluate.js +210 -0
  53. package/dist/core/evaluate.js.map +1 -0
  54. package/dist/core/filters.d.ts +51 -0
  55. package/dist/core/filters.d.ts.map +1 -0
  56. package/dist/core/filters.js +303 -0
  57. package/dist/core/filters.js.map +1 -0
  58. package/dist/core/format.d.ts +14 -0
  59. package/dist/core/format.d.ts.map +1 -0
  60. package/dist/core/format.js +303 -0
  61. package/dist/core/format.js.map +1 -0
  62. package/dist/core/measures.d.ts +26 -0
  63. package/dist/core/measures.d.ts.map +1 -0
  64. package/dist/core/measures.js +105 -0
  65. package/dist/core/measures.js.map +1 -0
  66. package/dist/core/request-ids.d.ts +20 -0
  67. package/dist/core/request-ids.d.ts.map +1 -0
  68. package/dist/core/request-ids.js +55 -0
  69. package/dist/core/request-ids.js.map +1 -0
  70. package/dist/core/rows.d.ts +79 -0
  71. package/dist/core/rows.d.ts.map +1 -0
  72. package/dist/core/rows.js +173 -0
  73. package/dist/core/rows.js.map +1 -0
  74. package/dist/core/store.d.ts +233 -0
  75. package/dist/core/store.d.ts.map +1 -0
  76. package/dist/core/store.js +1162 -0
  77. package/dist/core/store.js.map +1 -0
  78. package/dist/core/totals.d.ts +24 -0
  79. package/dist/core/totals.d.ts.map +1 -0
  80. package/dist/core/totals.js +49 -0
  81. package/dist/core/totals.js.map +1 -0
  82. package/dist/core/trace.d.ts +7 -0
  83. package/dist/core/trace.d.ts.map +1 -0
  84. package/dist/core/trace.js +26 -0
  85. package/dist/core/trace.js.map +1 -0
  86. package/dist/core/transports.d.ts +50 -0
  87. package/dist/core/transports.d.ts.map +1 -0
  88. package/dist/core/transports.js +160 -0
  89. package/dist/core/transports.js.map +1 -0
  90. package/dist/core/types.d.ts +150 -0
  91. package/dist/core/types.d.ts.map +1 -0
  92. package/dist/core/types.js +45 -0
  93. package/dist/core/types.js.map +1 -0
  94. package/dist/core.d.ts +12 -0
  95. package/dist/core.d.ts.map +1 -0
  96. package/dist/core.js +11 -0
  97. package/dist/core.js.map +1 -0
  98. package/dist/index.d.ts +15 -6
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +13 -7
  101. package/dist/index.js.map +1 -1
  102. package/dist/react/accessible-rows.d.ts +13 -0
  103. package/dist/react/accessible-rows.d.ts.map +1 -0
  104. package/dist/react/accessible-rows.js +320 -0
  105. package/dist/react/accessible-rows.js.map +1 -0
  106. package/dist/react/cell-editor.d.ts +22 -0
  107. package/dist/react/cell-editor.d.ts.map +1 -0
  108. package/dist/react/cell-editor.js +431 -0
  109. package/dist/react/cell-editor.js.map +1 -0
  110. package/dist/react/cell-menu.d.ts +18 -0
  111. package/dist/react/cell-menu.d.ts.map +1 -0
  112. package/dist/react/cell-menu.js +299 -0
  113. package/dist/react/cell-menu.js.map +1 -0
  114. package/dist/react/column-menu.d.ts +16 -0
  115. package/dist/react/column-menu.d.ts.map +1 -0
  116. package/dist/react/column-menu.js +1311 -0
  117. package/dist/react/column-menu.js.map +1 -0
  118. package/dist/react/columns-menu.d.ts +7 -0
  119. package/dist/react/columns-menu.d.ts.map +1 -0
  120. package/dist/react/columns-menu.js +249 -0
  121. package/dist/react/columns-menu.js.map +1 -0
  122. package/dist/react/conditions-menu.d.ts +10 -0
  123. package/dist/react/conditions-menu.d.ts.map +1 -0
  124. package/dist/react/conditions-menu.js +795 -0
  125. package/dist/react/conditions-menu.js.map +1 -0
  126. package/dist/react/context.d.ts +29 -0
  127. package/dist/react/context.d.ts.map +1 -0
  128. package/dist/react/context.js +18 -0
  129. package/dist/react/context.js.map +1 -0
  130. package/dist/react/data-grid.d.ts +79 -0
  131. package/dist/react/data-grid.d.ts.map +1 -0
  132. package/dist/react/data-grid.js +653 -0
  133. package/dist/react/data-grid.js.map +1 -0
  134. package/dist/react/detail-panel.d.ts +22 -0
  135. package/dist/react/detail-panel.d.ts.map +1 -0
  136. package/dist/react/detail-panel.js +242 -0
  137. package/dist/react/detail-panel.js.map +1 -0
  138. package/dist/react/export-menu.d.ts +11 -0
  139. package/dist/react/export-menu.d.ts.map +1 -0
  140. package/dist/react/export-menu.js +304 -0
  141. package/dist/react/export-menu.js.map +1 -0
  142. package/dist/react/find-bar.d.ts +11 -0
  143. package/dist/react/find-bar.d.ts.map +1 -0
  144. package/dist/react/find-bar.js +303 -0
  145. package/dist/react/find-bar.js.map +1 -0
  146. package/dist/react/format-form.d.ts +12 -0
  147. package/dist/react/format-form.d.ts.map +1 -0
  148. package/dist/react/format-form.js +863 -0
  149. package/dist/react/format-form.js.map +1 -0
  150. package/dist/react/formula-menu.d.ts +6 -0
  151. package/dist/react/formula-menu.d.ts.map +1 -0
  152. package/dist/react/formula-menu.js +343 -0
  153. package/dist/react/formula-menu.js.map +1 -0
  154. package/dist/react/grid-body.d.ts +33 -0
  155. package/dist/react/grid-body.d.ts.map +1 -0
  156. package/dist/react/grid-body.js +1389 -0
  157. package/dist/react/grid-body.js.map +1 -0
  158. package/dist/react/group-menu.d.ts +7 -0
  159. package/dist/react/group-menu.d.ts.map +1 -0
  160. package/dist/react/group-menu.js +508 -0
  161. package/dist/react/group-menu.js.map +1 -0
  162. package/dist/react/hooks.d.ts +33 -0
  163. package/dist/react/hooks.d.ts.map +1 -0
  164. package/dist/react/hooks.js +161 -0
  165. package/dist/react/hooks.js.map +1 -0
  166. package/dist/react/messages.d.ts +180 -0
  167. package/dist/react/messages.d.ts.map +1 -0
  168. package/dist/react/messages.js +414 -0
  169. package/dist/react/messages.js.map +1 -0
  170. package/dist/react/save.d.ts +9 -0
  171. package/dist/react/save.d.ts.map +1 -0
  172. package/dist/react/save.js +102 -0
  173. package/dist/react/save.js.map +1 -0
  174. package/dist/react/static-rows.d.ts +9 -0
  175. package/dist/react/static-rows.d.ts.map +1 -0
  176. package/dist/react/static-rows.js +176 -0
  177. package/dist/react/static-rows.js.map +1 -0
  178. package/dist/react/status-bar.d.ts +12 -0
  179. package/dist/react/status-bar.d.ts.map +1 -0
  180. package/dist/react/status-bar.js +413 -0
  181. package/dist/react/status-bar.js.map +1 -0
  182. package/dist/react/toolbar-popover.d.ts +14 -0
  183. package/dist/react/toolbar-popover.d.ts.map +1 -0
  184. package/dist/react/toolbar-popover.js +143 -0
  185. package/dist/react/toolbar-popover.js.map +1 -0
  186. package/dist/react/toolbar.d.ts +13 -0
  187. package/dist/react/toolbar.d.ts.map +1 -0
  188. package/dist/react/toolbar.js +344 -0
  189. package/dist/react/toolbar.js.map +1 -0
  190. package/dist/server.d.ts +22 -0
  191. package/dist/server.d.ts.map +1 -0
  192. package/dist/server.js +45 -0
  193. package/dist/server.js.map +1 -0
  194. package/dist/styles.css +496 -316
  195. package/package.json +42 -17
  196. package/src/canvas/geometry.ts +197 -0
  197. package/src/canvas/grid-canvas.ts +1222 -0
  198. package/src/canvas/hooks.ts +61 -0
  199. package/src/canvas/keys.ts +96 -0
  200. package/src/canvas/layout.ts +77 -0
  201. package/src/canvas/scroll.ts +120 -0
  202. package/src/canvas/text.ts +155 -0
  203. package/src/{theme.ts → canvas/theme.ts} +14 -1
  204. package/src/core/cache.ts +247 -0
  205. package/src/core/checked.ts +64 -0
  206. package/src/core/client.ts +103 -0
  207. package/src/core/conditions.ts +89 -0
  208. package/src/core/evaluate.ts +221 -0
  209. package/src/core/filters.ts +268 -0
  210. package/src/core/format.ts +309 -0
  211. package/src/core/measures.ts +99 -0
  212. package/src/core/request-ids.ts +54 -0
  213. package/src/core/rows.ts +213 -0
  214. package/src/core/store.ts +1122 -0
  215. package/src/core/totals.ts +59 -0
  216. package/src/core/trace.ts +44 -0
  217. package/src/core/transports.ts +177 -0
  218. package/src/core/types.ts +168 -0
  219. package/src/core.ts +39 -0
  220. package/src/index.ts +24 -12
  221. package/src/react/accessible-rows.tsx +242 -0
  222. package/src/react/cell-editor.tsx +216 -0
  223. package/src/react/cell-menu.tsx +166 -0
  224. package/src/react/column-menu.tsx +619 -0
  225. package/src/react/columns-menu.tsx +116 -0
  226. package/src/react/conditions-menu.tsx +289 -0
  227. package/src/react/context.ts +33 -0
  228. package/src/react/data-grid.tsx +286 -0
  229. package/src/react/detail-panel.tsx +92 -0
  230. package/src/react/export-menu.tsx +112 -0
  231. package/src/react/find-bar.tsx +112 -0
  232. package/src/react/format-form.tsx +421 -0
  233. package/src/react/formula-menu.tsx +163 -0
  234. package/src/react/grid-body.tsx +744 -0
  235. package/src/react/group-menu.tsx +214 -0
  236. package/src/react/hooks.ts +104 -0
  237. package/src/react/messages.ts +556 -0
  238. package/src/react/save.ts +42 -0
  239. package/src/react/static-rows.tsx +59 -0
  240. package/src/react/status-bar.tsx +175 -0
  241. package/src/react/toolbar-popover.tsx +69 -0
  242. package/src/react/toolbar.tsx +152 -0
  243. package/src/server.ts +58 -0
  244. package/src/styles.css +496 -316
  245. package/dist/components/bars.d.ts +0 -14
  246. package/dist/components/bars.d.ts.map +0 -1
  247. package/dist/components/bars.js +0 -68
  248. package/dist/components/bars.js.map +0 -1
  249. package/dist/components/cell-inspector.d.ts +0 -11
  250. package/dist/components/cell-inspector.d.ts.map +0 -1
  251. package/dist/components/cell-inspector.js +0 -37
  252. package/dist/components/cell-inspector.js.map +0 -1
  253. package/dist/components/columns-panel.d.ts +0 -12
  254. package/dist/components/columns-panel.d.ts.map +0 -1
  255. package/dist/components/columns-panel.js +0 -11
  256. package/dist/components/columns-panel.js.map +0 -1
  257. package/dist/components/filter-panel.d.ts +0 -22
  258. package/dist/components/filter-panel.d.ts.map +0 -1
  259. package/dist/components/filter-panel.js +0 -169
  260. package/dist/components/filter-panel.js.map +0 -1
  261. package/dist/components/find-bar.d.ts +0 -9
  262. package/dist/components/find-bar.d.ts.map +0 -1
  263. package/dist/components/find-bar.js +0 -46
  264. package/dist/components/find-bar.js.map +0 -1
  265. package/dist/components/popover.d.ts +0 -38
  266. package/dist/components/popover.d.ts.map +0 -1
  267. package/dist/components/popover.js +0 -104
  268. package/dist/components/popover.js.map +0 -1
  269. package/dist/components/stats-panel.d.ts +0 -12
  270. package/dist/components/stats-panel.d.ts.map +0 -1
  271. package/dist/components/stats-panel.js +0 -40
  272. package/dist/components/stats-panel.js.map +0 -1
  273. package/dist/controller.d.ts +0 -227
  274. package/dist/controller.d.ts.map +0 -1
  275. package/dist/controller.js +0 -845
  276. package/dist/controller.js.map +0 -1
  277. package/dist/data-grid.d.ts +0 -51
  278. package/dist/data-grid.d.ts.map +0 -1
  279. package/dist/data-grid.js +0 -704
  280. package/dist/data-grid.js.map +0 -1
  281. package/dist/labels.d.ts +0 -9
  282. package/dist/labels.d.ts.map +0 -1
  283. package/dist/labels.js +0 -38
  284. package/dist/labels.js.map +0 -1
  285. package/dist/messages.d.ts +0 -99
  286. package/dist/messages.d.ts.map +0 -1
  287. package/dist/messages.js +0 -276
  288. package/dist/messages.js.map +0 -1
  289. package/dist/renderer.d.ts +0 -52
  290. package/dist/renderer.d.ts.map +0 -1
  291. package/dist/renderer.js +0 -522
  292. package/dist/renderer.js.map +0 -1
  293. package/dist/text.d.ts +0 -14
  294. package/dist/text.d.ts.map +0 -1
  295. package/dist/text.js +0 -63
  296. package/dist/text.js.map +0 -1
  297. package/dist/theme.d.ts.map +0 -1
  298. package/dist/theme.js +0 -54
  299. package/dist/theme.js.map +0 -1
  300. package/src/components/bars.tsx +0 -180
  301. package/src/components/cell-inspector.tsx +0 -70
  302. package/src/components/columns-panel.tsx +0 -59
  303. package/src/components/filter-panel.tsx +0 -293
  304. package/src/components/find-bar.tsx +0 -104
  305. package/src/components/popover.tsx +0 -194
  306. package/src/components/stats-panel.tsx +0 -153
  307. package/src/controller.ts +0 -945
  308. package/src/data-grid.tsx +0 -1035
  309. package/src/labels.ts +0 -46
  310. package/src/messages.ts +0 -390
  311. package/src/renderer.ts +0 -535
  312. package/src/text.ts +0 -55
@@ -0,0 +1,73 @@
1
+ /** Positions of columns laid out side by side. Lookups are O(1) by index and O(log n) by x. */
2
+ export class ColumnLayout {
3
+ /** `offsets[i]` is the left edge of column `i`; `offsets[count]` is the total width. */
4
+
5
+ constructor(widths) {
6
+ this.offsets = new Float64Array(widths.length + 1);
7
+ for (let index = 0; index < widths.length; index++) {
8
+ this.offsets[index + 1] = this.offsets[index] + Math.max(0, widths[index]);
9
+ }
10
+ }
11
+ get count() {
12
+ return this.offsets.length - 1;
13
+ }
14
+ get total() {
15
+ return this.offsets[this.count];
16
+ }
17
+ left(index) {
18
+ return this.offsets[index];
19
+ }
20
+ right(index) {
21
+ return this.offsets[index + 1];
22
+ }
23
+ width(index) {
24
+ return this.offsets[index + 1] - this.offsets[index];
25
+ }
26
+
27
+ /** The column containing `x`, clamped to the existing columns. Returns -1 when there are none. */
28
+ indexAt(x) {
29
+ const count = this.count;
30
+ if (count === 0) return -1;
31
+ if (x <= 0) return 0;
32
+ if (x >= this.total) return count - 1;
33
+ let low = 0;
34
+ let high = count - 1;
35
+ while (low < high) {
36
+ const middle = low + high + 1 >> 1;
37
+ if (this.offsets[middle] <= x) low = middle;else high = middle - 1;
38
+ }
39
+ return low;
40
+ }
41
+ }
42
+
43
+ /** Where a column is frozen: at the left, at the right, or not (`null`, it scrolls). */
44
+
45
+ /**
46
+ * Share of the body's width (without the row header) that frozen columns may take together. Columns
47
+ * frozen beyond it scroll with the others until the grid is wide enough again, so that the scrolling
48
+ * columns always keep some room.
49
+ */
50
+ const MAX_FROZEN_SHARE = 0.75;
51
+
52
+ /**
53
+ * The columns drawn frozen at each side: the first `left` and the last `right` columns of `layout`, fewer
54
+ * when together they are wider than `MAX_FROZEN_SHARE` of `available` (the body's width). Columns frozen
55
+ * at the right give way first, then those at the left, each from the scrolling side. With an unknown
56
+ * width (`available` 0 or less) every frozen column stays frozen.
57
+ */
58
+ export function fitFrozen(layout, left, right, available) {
59
+ const count = layout.count;
60
+ let fittedLeft = Math.max(0, Math.min(Math.floor(left), count));
61
+ let fittedRight = Math.max(0, Math.min(Math.floor(right), count - fittedLeft));
62
+ if (available > 0) {
63
+ const limit = available * MAX_FROZEN_SHARE;
64
+ const width = () => layout.left(fittedLeft) + layout.total - layout.left(count - fittedRight);
65
+ while (fittedRight > 0 && width() > limit) fittedRight--;
66
+ while (fittedLeft > 0 && width() > limit) fittedLeft--;
67
+ }
68
+ return {
69
+ left: fittedLeft,
70
+ right: fittedRight
71
+ };
72
+ }
73
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ColumnLayout","constructor","widths","offsets","Float64Array","length","index","Math","max","count","total","left","right","width","indexAt","x","low","high","middle","MAX_FROZEN_SHARE","fitFrozen","layout","available","fittedLeft","min","floor","fittedRight","limit"],"sources":["layout.ts"],"sourcesContent":["/** Positions of columns laid out side by side. Lookups are O(1) by index and O(log n) by x. */\nexport class ColumnLayout {\n /** `offsets[i]` is the left edge of column `i`; `offsets[count]` is the total width. */\n readonly offsets: Float64Array;\n\n constructor(widths: ArrayLike<number>) {\n this.offsets = new Float64Array(widths.length + 1);\n for (let index = 0; index < widths.length; index++) {\n this.offsets[index + 1] = this.offsets[index] + Math.max(0, widths[index]);\n }\n }\n\n get count() {\n return this.offsets.length - 1;\n }\n\n get total() {\n return this.offsets[this.count];\n }\n\n left(index: number) {\n return this.offsets[index];\n }\n\n right(index: number) {\n return this.offsets[index + 1];\n }\n\n width(index: number) {\n return this.offsets[index + 1] - this.offsets[index];\n }\n\n /** The column containing `x`, clamped to the existing columns. Returns -1 when there are none. */\n indexAt(x: number): number {\n const count = this.count;\n if (count === 0) return -1;\n if (x <= 0) return 0;\n if (x >= this.total) return count - 1;\n let low = 0;\n let high = count - 1;\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n if (this.offsets[middle] <= x) low = middle;\n else high = middle - 1;\n }\n return low;\n }\n}\n\n/** Where a column is frozen: at the left, at the right, or not (`null`, it scrolls). */\nexport type ColumnPin = \"left\" | \"right\" | null;\n\n/**\n * Share of the body's width (without the row header) that frozen columns may take together. Columns\n * frozen beyond it scroll with the others until the grid is wide enough again, so that the scrolling\n * columns always keep some room.\n */\nconst MAX_FROZEN_SHARE = 0.75;\n\n/**\n * The columns drawn frozen at each side: the first `left` and the last `right` columns of `layout`, fewer\n * when together they are wider than `MAX_FROZEN_SHARE` of `available` (the body's width). Columns frozen\n * at the right give way first, then those at the left, each from the scrolling side. With an unknown\n * width (`available` 0 or less) every frozen column stays frozen.\n */\nexport function fitFrozen(layout: ColumnLayout, left: number, right: number, available: number) {\n const count = layout.count;\n let fittedLeft = Math.max(0, Math.min(Math.floor(left), count));\n let fittedRight = Math.max(0, Math.min(Math.floor(right), count - fittedLeft));\n if (available > 0) {\n const limit = available * MAX_FROZEN_SHARE;\n const width = () => layout.left(fittedLeft) + layout.total - layout.left(count - fittedRight);\n while (fittedRight > 0 && width() > limit) fittedRight--;\n while (fittedLeft > 0 && width() > limit) fittedLeft--;\n }\n return { left: fittedLeft, right: fittedRight };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ export declare class ScrollAxis {
2
+ private readonly maxNative;
3
+ private contentSize;
4
+ private viewportSize;
5
+ private nativeSize;
6
+ private virtual;
7
+ private lastNative;
8
+ private expectedNative;
9
+ private expectedVirtual;
10
+ constructor(maxNative?: number);
11
+ /** Updates the sizes and returns the size to give the native scroll content. */
12
+ resize(contentSize: number, viewportSize: number): number;
13
+ /** Whether the native position is mapped (the content is larger than `maxNative`). */
14
+ get scaled(): boolean;
15
+ get virtualRange(): number;
16
+ get nativeRange(): number;
17
+ /** The current virtual position. */
18
+ get position(): number;
19
+ /** The native position that corresponds to the current state. */
20
+ get native(): number;
21
+ private jumpThreshold;
22
+ /** Handles a native scroll event and returns the new virtual position. */
23
+ onNativeScroll(nativePosition: number): number;
24
+ /**
25
+ * Moves to a virtual position and returns the native position to assign to the scroll element.
26
+ * Nearby targets move the native position by the same amount, so a following wheel scroll
27
+ * continues smoothly; distant targets map proportionally.
28
+ */
29
+ scrollTo(target: number): number;
30
+ }
31
+ //# sourceMappingURL=scroll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll.d.ts","sourceRoot":"","sources":["../../src/canvas/scroll.ts"],"names":[],"mappings":"AAmBA,qBAAa,UAAU;IAST,OAAO,CAAC,QAAQ,CAAC,SAAS;IARtC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,eAAe,CAAK;IAE5B,YAA6B,SAAS,SAAoB,EAAI;IAE9D,gFAAgF;IAChF,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAMxD;IAED,sFAAsF;IACtF,IAAI,MAAM,YAET;IAED,IAAI,YAAY,WAEf;IAED,IAAI,WAAW,WAEd;IAED,oCAAoC;IACpC,IAAI,QAAQ,WAEX;IAED,iEAAiE;IACjE,IAAI,MAAM,WAET;IAED,OAAO,CAAC,aAAa;IAIrB,0EAA0E;IAC1E,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAwB7C;IAED;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoB/B;CACF"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Browsers cap the size of an element (about 16.7M px in Chromium, 17.9M px in Firefox, 33.5M px
3
+ * in Safari). With 24 px rows that is well under a million rows, so a native scrollbar cannot
4
+ * cover the content of a large table. `ScrollAxis` maps a native scroll position, kept below
5
+ * `maxNative`, onto a much larger virtual position:
6
+ *
7
+ * - Small movements (wheel, trackpad, arrow keys) move the virtual position by the same amount, so
8
+ * scrolling feels exactly like a normal page at any depth.
9
+ * - Large jumps (dragging the thumb, clicking the track) and the two ends map proportionally, so the
10
+ * scrollbar still tells where you are and reaches the first and the last row.
11
+ *
12
+ * Content smaller than `maxNative` is never scaled.
13
+ */
14
+ const MAX_NATIVE_SCROLL = 8_000_000;
15
+ function clamp(value, min, max) {
16
+ return Math.min(Math.max(value, min), max);
17
+ }
18
+ export class ScrollAxis {
19
+ contentSize = 0;
20
+ viewportSize = 0;
21
+ nativeSize = 0;
22
+ virtual = 0;
23
+ lastNative = 0;
24
+ expectedNative = null;
25
+ expectedVirtual = 0;
26
+ constructor(maxNative = MAX_NATIVE_SCROLL) {
27
+ this.maxNative = maxNative;
28
+ }
29
+
30
+ /** Updates the sizes and returns the size to give the native scroll content. */
31
+ resize(contentSize, viewportSize) {
32
+ this.contentSize = Math.max(0, contentSize);
33
+ this.viewportSize = Math.max(0, viewportSize);
34
+ this.nativeSize = Math.min(this.contentSize, this.maxNative);
35
+ this.virtual = clamp(this.virtual, 0, this.virtualRange);
36
+ return this.nativeSize;
37
+ }
38
+
39
+ /** Whether the native position is mapped (the content is larger than `maxNative`). */
40
+ get scaled() {
41
+ return this.contentSize > this.maxNative;
42
+ }
43
+ get virtualRange() {
44
+ return Math.max(0, this.contentSize - this.viewportSize);
45
+ }
46
+ get nativeRange() {
47
+ return Math.max(0, this.nativeSize - this.viewportSize);
48
+ }
49
+
50
+ /** The current virtual position. */
51
+ get position() {
52
+ return this.virtual;
53
+ }
54
+
55
+ /** The native position that corresponds to the current state. */
56
+ get native() {
57
+ return this.lastNative;
58
+ }
59
+ jumpThreshold() {
60
+ return Math.max(this.viewportSize * 2, 1000);
61
+ }
62
+
63
+ /** Handles a native scroll event and returns the new virtual position. */
64
+ onNativeScroll(nativePosition) {
65
+ const nativeRange = this.nativeRange;
66
+ const native = clamp(nativePosition, 0, nativeRange);
67
+ if (this.expectedNative !== null && Math.abs(native - this.expectedNative) <= 1) {
68
+ // The event caused by `scrollTo`. Browsers may round the position, so keep the requested one.
69
+ this.expectedNative = null;
70
+ this.lastNative = native;
71
+ this.virtual = this.expectedVirtual;
72
+ return this.virtual;
73
+ }
74
+ this.expectedNative = null;
75
+ if (!this.scaled) {
76
+ this.lastNative = native;
77
+ this.virtual = native;
78
+ return native;
79
+ }
80
+ const delta = native - this.lastNative;
81
+ this.lastNative = native;
82
+ const virtualRange = this.virtualRange;
83
+ if (native <= 0) this.virtual = 0;else if (native >= nativeRange) this.virtual = virtualRange;else if (Math.abs(delta) > this.jumpThreshold()) this.virtual = native / nativeRange * virtualRange;else this.virtual = clamp(this.virtual + delta, 0, virtualRange);
84
+ return this.virtual;
85
+ }
86
+
87
+ /**
88
+ * Moves to a virtual position and returns the native position to assign to the scroll element.
89
+ * Nearby targets move the native position by the same amount, so a following wheel scroll
90
+ * continues smoothly; distant targets map proportionally.
91
+ */
92
+ scrollTo(target) {
93
+ const virtualRange = this.virtualRange;
94
+ const virtual = clamp(target, 0, virtualRange);
95
+ let native;
96
+ if (!this.scaled) {
97
+ native = virtual;
98
+ } else {
99
+ const nativeRange = this.nativeRange;
100
+ const delta = virtual - this.virtual;
101
+ const local = this.lastNative + delta;
102
+ if (virtual === 0) native = 0;else if (virtual === virtualRange) native = nativeRange;else if (Math.abs(delta) <= this.jumpThreshold() && local > 0 && local < nativeRange) native = local;else native = virtualRange === 0 ? 0 : virtual / virtualRange * nativeRange;
103
+ }
104
+ this.virtual = virtual;
105
+ this.expectedVirtual = virtual;
106
+ this.expectedNative = native;
107
+ this.lastNative = native;
108
+ return native;
109
+ }
110
+ }
111
+ //# sourceMappingURL=scroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["MAX_NATIVE_SCROLL","clamp","value","min","max","Math","ScrollAxis","contentSize","viewportSize","nativeSize","virtual","lastNative","expectedNative","expectedVirtual","constructor","maxNative","resize","virtualRange","scaled","nativeRange","position","native","jumpThreshold","onNativeScroll","nativePosition","abs","delta","scrollTo","target","local"],"sources":["scroll.ts"],"sourcesContent":["/**\n * Browsers cap the size of an element (about 16.7M px in Chromium, 17.9M px in Firefox, 33.5M px\n * in Safari). With 24 px rows that is well under a million rows, so a native scrollbar cannot\n * cover the content of a large table. `ScrollAxis` maps a native scroll position, kept below\n * `maxNative`, onto a much larger virtual position:\n *\n * - Small movements (wheel, trackpad, arrow keys) move the virtual position by the same amount, so\n * scrolling feels exactly like a normal page at any depth.\n * - Large jumps (dragging the thumb, clicking the track) and the two ends map proportionally, so the\n * scrollbar still tells where you are and reaches the first and the last row.\n *\n * Content smaller than `maxNative` is never scaled.\n */\nconst MAX_NATIVE_SCROLL = 8_000_000;\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n}\n\nexport class ScrollAxis {\n private contentSize = 0;\n private viewportSize = 0;\n private nativeSize = 0;\n private virtual = 0;\n private lastNative = 0;\n private expectedNative: number | null = null;\n private expectedVirtual = 0;\n\n constructor(private readonly maxNative = MAX_NATIVE_SCROLL) {}\n\n /** Updates the sizes and returns the size to give the native scroll content. */\n resize(contentSize: number, viewportSize: number): number {\n this.contentSize = Math.max(0, contentSize);\n this.viewportSize = Math.max(0, viewportSize);\n this.nativeSize = Math.min(this.contentSize, this.maxNative);\n this.virtual = clamp(this.virtual, 0, this.virtualRange);\n return this.nativeSize;\n }\n\n /** Whether the native position is mapped (the content is larger than `maxNative`). */\n get scaled() {\n return this.contentSize > this.maxNative;\n }\n\n get virtualRange() {\n return Math.max(0, this.contentSize - this.viewportSize);\n }\n\n get nativeRange() {\n return Math.max(0, this.nativeSize - this.viewportSize);\n }\n\n /** The current virtual position. */\n get position() {\n return this.virtual;\n }\n\n /** The native position that corresponds to the current state. */\n get native() {\n return this.lastNative;\n }\n\n private jumpThreshold() {\n return Math.max(this.viewportSize * 2, 1000);\n }\n\n /** Handles a native scroll event and returns the new virtual position. */\n onNativeScroll(nativePosition: number): number {\n const nativeRange = this.nativeRange;\n const native = clamp(nativePosition, 0, nativeRange);\n if (this.expectedNative !== null && Math.abs(native - this.expectedNative) <= 1) {\n // The event caused by `scrollTo`. Browsers may round the position, so keep the requested one.\n this.expectedNative = null;\n this.lastNative = native;\n this.virtual = this.expectedVirtual;\n return this.virtual;\n }\n this.expectedNative = null;\n if (!this.scaled) {\n this.lastNative = native;\n this.virtual = native;\n return native;\n }\n const delta = native - this.lastNative;\n this.lastNative = native;\n const virtualRange = this.virtualRange;\n if (native <= 0) this.virtual = 0;\n else if (native >= nativeRange) this.virtual = virtualRange;\n else if (Math.abs(delta) > this.jumpThreshold()) this.virtual = (native / nativeRange) * virtualRange;\n else this.virtual = clamp(this.virtual + delta, 0, virtualRange);\n return this.virtual;\n }\n\n /**\n * Moves to a virtual position and returns the native position to assign to the scroll element.\n * Nearby targets move the native position by the same amount, so a following wheel scroll\n * continues smoothly; distant targets map proportionally.\n */\n scrollTo(target: number): number {\n const virtualRange = this.virtualRange;\n const virtual = clamp(target, 0, virtualRange);\n let native: number;\n if (!this.scaled) {\n native = virtual;\n } else {\n const nativeRange = this.nativeRange;\n const delta = virtual - this.virtual;\n const local = this.lastNative + delta;\n if (virtual === 0) native = 0;\n else if (virtual === virtualRange) native = nativeRange;\n else if (Math.abs(delta) <= this.jumpThreshold() && local > 0 && local < nativeRange) native = local;\n else native = virtualRange === 0 ? 0 : (virtual / virtualRange) * nativeRange;\n }\n this.virtual = virtual;\n this.expectedVirtual = virtual;\n this.expectedNative = native;\n this.lastNative = native;\n return native;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,23 @@
1
+ /** Measures and shortens text for one font, caching results because the same strings repeat a lot. */
2
+ export declare class TextFitter {
3
+ private readonly context;
4
+ readonly font: string;
5
+ private readonly widths;
6
+ private readonly fits;
7
+ private readonly wrapped;
8
+ private ellipsisWidth;
9
+ constructor(context: CanvasRenderingContext2D, font: string);
10
+ /** Width of `text`. The caller must have set `context.font` to this fitter's font. */
11
+ width(text: string): number;
12
+ /** `text`, shortened with "…" to fit in `maxWidth`. */
13
+ fit(text: string, maxWidth: number): string;
14
+ /**
15
+ * `text` wrapped onto at most `maxLines` lines of `maxWidth`: lines break at spaces and between CJK
16
+ * characters (not before closing punctuation or after opening brackets), words longer than a line
17
+ * are cut, and "\n" starts a new line. When the text needs more lines, the last one ends with "…".
18
+ */
19
+ lines(text: string, maxWidth: number, maxLines: number): readonly string[];
20
+ /** Length of the first line of `text` (one paragraph) in `maxWidth`, at a place where it may break. */
21
+ private breakAt;
22
+ }
23
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/canvas/text.ts"],"names":[],"mappings":"AAuCA,sGAAsG;AACtG,qBAAa,UAAU;IAOnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAPvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;IAChE,OAAO,CAAC,aAAa,CAAM;IAE3B,YACmB,OAAO,EAAE,wBAAwB,EACzC,IAAI,EAAE,MAAM,EACnB;IAEJ,sFAAsF;IACtF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ1B;IAED,uDAAuD;IACvD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2B1C;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAsCzE;IAED,uGAAuG;IACvG,OAAO,CAAC,OAAO;CAgBhB"}
@@ -0,0 +1,142 @@
1
+ const ELLIPSIS = "…";
2
+ const MAX_ENTRIES = 20_000;
3
+ /** Characters that do not start a line (closing brackets, Japanese punctuation and small kana). */
4
+ const NO_START = new Set(")]}>,.!?:;%、。,.・:;?!‼⁇⁈⁉ー〜~)」』】〕〉》}〙〗〟’”ゝゞヽヾ々〻ぁぃぅぇぉっゃゅょゎゕゖァィゥェォッャュョヮヵヶㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ");
5
+ /** Characters that do not end a line (opening brackets). */
6
+ const NO_END = new Set("([{<(「『【〔〈《{〘〖〝‘“");
7
+
8
+ /** Whether a UTF-16 code unit belongs to a script written without spaces (CJK, kana, Hangul, full width). */
9
+ function isWide(code) {
10
+ return code >= 0x1100 && code <= 0x11ff || code >= 0x2e80 && code <= 0x9fff || code >= 0xa960 && code <= 0xa97f || code >= 0xac00 && code <= 0xd7ff ||
11
+ // Surrogates of the CJK extensions (U+20000–U+3FFFF).
12
+ code >= 0xd840 && code <= 0xd8bf || code >= 0xf900 && code <= 0xfaff || code >= 0xfe30 && code <= 0xfe4f || code >= 0xff00 && code <= 0xffef;
13
+ }
14
+ function isHighSurrogate(code) {
15
+ return code >= 0xd800 && code <= 0xdbff;
16
+ }
17
+
18
+ /** Whether a line may break between `text[index - 1]` and `text[index]`. */
19
+ function canBreak(text, index) {
20
+ const before = text[index - 1];
21
+ const after = text[index];
22
+ if (before === " " || after === " ") return true;
23
+ if (NO_START.has(after) || NO_END.has(before)) return false;
24
+ const code = text.charCodeAt(index - 1);
25
+ if (isHighSurrogate(code)) return false;
26
+ return isWide(code) || isWide(text.charCodeAt(index));
27
+ }
28
+
29
+ /** Measures and shortens text for one font, caching results because the same strings repeat a lot. */
30
+ export class TextFitter {
31
+ widths = new Map();
32
+ fits = new Map();
33
+ wrapped = new Map();
34
+ ellipsisWidth = -1;
35
+ constructor(context, font) {
36
+ this.context = context;
37
+ this.font = font;
38
+ }
39
+
40
+ /** Width of `text`. The caller must have set `context.font` to this fitter's font. */
41
+ width(text) {
42
+ let width = this.widths.get(text);
43
+ if (width === undefined) {
44
+ width = this.context.measureText(text).width;
45
+ if (this.widths.size > MAX_ENTRIES) this.widths.clear();
46
+ this.widths.set(text, width);
47
+ }
48
+ return width;
49
+ }
50
+
51
+ /** `text`, shortened with "…" to fit in `maxWidth`. */
52
+ fit(text, maxWidth) {
53
+ if (maxWidth <= 0 || text === "") return "";
54
+ // Cells never show more than a few hundred characters; skip measuring the rest.
55
+ const source = text.length > 400 ? text.slice(0, 400) : text;
56
+ if (source === text && this.width(text) <= maxWidth) return text;
57
+ const key = `${Math.floor(maxWidth)}\u0001${source}`;
58
+ const cached = this.fits.get(key);
59
+ if (cached !== undefined) return cached;
60
+ if (this.ellipsisWidth < 0) this.ellipsisWidth = this.context.measureText(ELLIPSIS).width;
61
+ let result = "";
62
+ if (this.ellipsisWidth <= maxWidth) {
63
+ const full = this.context.measureText(source).width;
64
+ let low = 0;
65
+ let high = Math.min(source.length, Math.ceil(source.length * maxWidth / Math.max(1, full)) + 4);
66
+ while (low < high) {
67
+ const middle = low + high + 1 >> 1;
68
+ if (this.context.measureText(source.slice(0, middle)).width + this.ellipsisWidth <= maxWidth) low = middle;else high = middle - 1;
69
+ }
70
+ // Do not split a surrogate pair.
71
+ const code = source.charCodeAt(low - 1);
72
+ if (low > 0 && code >= 0xd800 && code <= 0xdbff) low--;
73
+ result = `${source.slice(0, low)}${ELLIPSIS}`;
74
+ }
75
+ if (this.fits.size > MAX_ENTRIES) this.fits.clear();
76
+ this.fits.set(key, result);
77
+ return result;
78
+ }
79
+
80
+ /**
81
+ * `text` wrapped onto at most `maxLines` lines of `maxWidth`: lines break at spaces and between CJK
82
+ * characters (not before closing punctuation or after opening brackets), words longer than a line
83
+ * are cut, and "\n" starts a new line. When the text needs more lines, the last one ends with "…".
84
+ */
85
+ lines(text, maxWidth, maxLines) {
86
+ if (maxWidth <= 0 || maxLines < 1) return [];
87
+ const source = text.replace(/\n+$/, "");
88
+ if (source === "") return [];
89
+ const key = `${Math.floor(maxWidth)}\u0001${maxLines}\u0001${source}`;
90
+ const cached = this.wrapped.get(key);
91
+ if (cached !== undefined) return cached;
92
+ const result = [];
93
+ const paragraphs = source.split("\n");
94
+ // The text the last line was taken from, and whether more text follows it.
95
+ let last = "";
96
+ let cut = false;
97
+ let more = false;
98
+ for (const paragraph of paragraphs) {
99
+ if (result.length === maxLines) {
100
+ more = true;
101
+ break;
102
+ }
103
+ let rest = paragraph;
104
+ do {
105
+ if (result.length === maxLines) {
106
+ more = cut = true;
107
+ break;
108
+ }
109
+ last = rest;
110
+ const end = this.breakAt(rest, maxWidth);
111
+ result.push(rest.slice(0, end).replace(/ +$/, ""));
112
+ rest = rest.slice(end).replace(/^ +/, "");
113
+ } while (rest !== "");
114
+ if (more) break;
115
+ }
116
+ if (more) {
117
+ const index = result.length - 1;
118
+ result[index] = this.fit(cut ? last : `${result[index]}${ELLIPSIS}`, maxWidth);
119
+ }
120
+ if (this.wrapped.size > MAX_ENTRIES) this.wrapped.clear();
121
+ this.wrapped.set(key, result);
122
+ return result;
123
+ }
124
+
125
+ /** Length of the first line of `text` (one paragraph) in `maxWidth`, at a place where it may break. */
126
+ breakAt(text, maxWidth) {
127
+ if (text === "" || this.width(text) <= maxWidth) return text.length;
128
+ // A character is at least a pixel wide, so a line has at most `maxWidth` characters.
129
+ let low = 0;
130
+ let high = Math.min(text.length, Math.ceil(maxWidth));
131
+ while (low < high) {
132
+ const middle = low + high + 1 >> 1;
133
+ if (this.context.measureText(text.slice(0, middle)).width <= maxWidth) low = middle;else high = middle - 1;
134
+ }
135
+ for (let index = low; index > 0; index--) if (canBreak(text, index)) return index;
136
+ // No place to break: cut the word, keeping surrogate pairs, and place at least one character.
137
+ let end = Math.max(1, low);
138
+ if (end < text.length && isHighSurrogate(text.charCodeAt(end - 1))) end = end > 1 ? end - 1 : end + 1;
139
+ return end;
140
+ }
141
+ }
142
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ELLIPSIS","MAX_ENTRIES","NO_START","Set","NO_END","isWide","code","isHighSurrogate","canBreak","text","index","before","after","has","charCodeAt","TextFitter","widths","Map","fits","wrapped","ellipsisWidth","constructor","context","font","width","get","undefined","measureText","size","clear","set","fit","maxWidth","source","length","slice","key","Math","floor","cached","result","full","low","high","min","ceil","max","middle","lines","maxLines","replace","paragraphs","split","last","cut","more","paragraph","rest","end","breakAt","push"],"sources":["text.ts"],"sourcesContent":["const ELLIPSIS = \"…\";\nconst MAX_ENTRIES = 20_000;\n/** Characters that do not start a line (closing brackets, Japanese punctuation and small kana). */\nconst NO_START = new Set(\n \")]}>,.!?:;%、。,.・:;?!‼⁇⁈⁉ー〜~)」』】〕〉》}〙〗〟’”ゝゞヽヾ々〻ぁぃぅぇぉっゃゅょゎゕゖァィゥェォッャュョヮヵヶㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ\",\n);\n/** Characters that do not end a line (opening brackets). */\nconst NO_END = new Set(\"([{<(「『【〔〈《{〘〖〝‘“\");\n\n/** Whether a UTF-16 code unit belongs to a script written without spaces (CJK, kana, Hangul, full width). */\nfunction isWide(code: number) {\n return (\n (code >= 0x1100 && code <= 0x11ff) ||\n (code >= 0x2e80 && code <= 0x9fff) ||\n (code >= 0xa960 && code <= 0xa97f) ||\n (code >= 0xac00 && code <= 0xd7ff) ||\n // Surrogates of the CJK extensions (U+20000–U+3FFFF).\n (code >= 0xd840 && code <= 0xd8bf) ||\n (code >= 0xf900 && code <= 0xfaff) ||\n (code >= 0xfe30 && code <= 0xfe4f) ||\n (code >= 0xff00 && code <= 0xffef)\n );\n}\n\nfunction isHighSurrogate(code: number) {\n return code >= 0xd800 && code <= 0xdbff;\n}\n\n/** Whether a line may break between `text[index - 1]` and `text[index]`. */\nfunction canBreak(text: string, index: number) {\n const before = text[index - 1];\n const after = text[index];\n if (before === \" \" || after === \" \") return true;\n if (NO_START.has(after) || NO_END.has(before)) return false;\n const code = text.charCodeAt(index - 1);\n if (isHighSurrogate(code)) return false;\n return isWide(code) || isWide(text.charCodeAt(index));\n}\n\n/** Measures and shortens text for one font, caching results because the same strings repeat a lot. */\nexport class TextFitter {\n private readonly widths = new Map<string, number>();\n private readonly fits = new Map<string, string>();\n private readonly wrapped = new Map<string, readonly string[]>();\n private ellipsisWidth = -1;\n\n constructor(\n private readonly context: CanvasRenderingContext2D,\n readonly font: string,\n ) {}\n\n /** Width of `text`. The caller must have set `context.font` to this fitter's font. */\n width(text: string): number {\n let width = this.widths.get(text);\n if (width === undefined) {\n width = this.context.measureText(text).width;\n if (this.widths.size > MAX_ENTRIES) this.widths.clear();\n this.widths.set(text, width);\n }\n return width;\n }\n\n /** `text`, shortened with \"…\" to fit in `maxWidth`. */\n fit(text: string, maxWidth: number): string {\n if (maxWidth <= 0 || text === \"\") return \"\";\n // Cells never show more than a few hundred characters; skip measuring the rest.\n const source = text.length > 400 ? text.slice(0, 400) : text;\n if (source === text && this.width(text) <= maxWidth) return text;\n const key = `${Math.floor(maxWidth)}\\u0001${source}`;\n const cached = this.fits.get(key);\n if (cached !== undefined) return cached;\n if (this.ellipsisWidth < 0) this.ellipsisWidth = this.context.measureText(ELLIPSIS).width;\n let result = \"\";\n if (this.ellipsisWidth <= maxWidth) {\n const full = this.context.measureText(source).width;\n let low = 0;\n let high = Math.min(source.length, Math.ceil((source.length * maxWidth) / Math.max(1, full)) + 4);\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n if (this.context.measureText(source.slice(0, middle)).width + this.ellipsisWidth <= maxWidth) low = middle;\n else high = middle - 1;\n }\n // Do not split a surrogate pair.\n const code = source.charCodeAt(low - 1);\n if (low > 0 && code >= 0xd800 && code <= 0xdbff) low--;\n result = `${source.slice(0, low)}${ELLIPSIS}`;\n }\n if (this.fits.size > MAX_ENTRIES) this.fits.clear();\n this.fits.set(key, result);\n return result;\n }\n\n /**\n * `text` wrapped onto at most `maxLines` lines of `maxWidth`: lines break at spaces and between CJK\n * characters (not before closing punctuation or after opening brackets), words longer than a line\n * are cut, and \"\\n\" starts a new line. When the text needs more lines, the last one ends with \"…\".\n */\n lines(text: string, maxWidth: number, maxLines: number): readonly string[] {\n if (maxWidth <= 0 || maxLines < 1) return [];\n const source = text.replace(/\\n+$/, \"\");\n if (source === \"\") return [];\n const key = `${Math.floor(maxWidth)}\\u0001${maxLines}\\u0001${source}`;\n const cached = this.wrapped.get(key);\n if (cached !== undefined) return cached;\n const result: string[] = [];\n const paragraphs = source.split(\"\\n\");\n // The text the last line was taken from, and whether more text follows it.\n let last = \"\";\n let cut = false;\n let more = false;\n for (const paragraph of paragraphs) {\n if (result.length === maxLines) {\n more = true;\n break;\n }\n let rest = paragraph;\n do {\n if (result.length === maxLines) {\n more = cut = true;\n break;\n }\n last = rest;\n const end = this.breakAt(rest, maxWidth);\n result.push(rest.slice(0, end).replace(/ +$/, \"\"));\n rest = rest.slice(end).replace(/^ +/, \"\");\n } while (rest !== \"\");\n if (more) break;\n }\n if (more) {\n const index = result.length - 1;\n result[index] = this.fit(cut ? last : `${result[index]}${ELLIPSIS}`, maxWidth);\n }\n if (this.wrapped.size > MAX_ENTRIES) this.wrapped.clear();\n this.wrapped.set(key, result);\n return result;\n }\n\n /** Length of the first line of `text` (one paragraph) in `maxWidth`, at a place where it may break. */\n private breakAt(text: string, maxWidth: number) {\n if (text === \"\" || this.width(text) <= maxWidth) return text.length;\n // A character is at least a pixel wide, so a line has at most `maxWidth` characters.\n let low = 0;\n let high = Math.min(text.length, Math.ceil(maxWidth));\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n if (this.context.measureText(text.slice(0, middle)).width <= maxWidth) low = middle;\n else high = middle - 1;\n }\n for (let index = low; index > 0; index--) if (canBreak(text, index)) return index;\n // No place to break: cut the word, keeping surrogate pairs, and place at least one character.\n let end = Math.max(1, low);\n if (end < text.length && isHighSurrogate(text.charCodeAt(end - 1))) end = end > 1 ? end - 1 : end + 1;\n return end;\n }\n}\n"],"mappings":"AAAA,MAAMA,QAAQ,GAAG,GAAG;AACpB,MAAMC,WAAW,GAAG,MAAM;AAC1B;AACA,MAAMC,QAAQ,GAAG,IAAIC,GAAG,CACtB,wFACF,CAAC;AACD;AACA,MAAMC,MAAM,GAAG,IAAID,GAAG,CAAC,mBAAmB,CAAC;;AAE3C;AACA,SAASE,MAAMA,CAACC,IAAY,EAAE;EAC5B,OACGA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAM,IAChCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO,IACjCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO,IACjCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO;EAClC;EACCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO,IACjCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO,IACjCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO,IACjCA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAO;AAEtC;AAEA,SAASC,eAAeA,CAACD,IAAY,EAAE;EACrC,OAAOA,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAM;AACzC;;AAEA;AACA,SAASE,QAAQA,CAACC,IAAY,EAAEC,KAAa,EAAE;EAC7C,MAAMC,MAAM,GAAGF,IAAI,CAACC,KAAK,GAAG,CAAC,CAAC;EAC9B,MAAME,KAAK,GAAGH,IAAI,CAACC,KAAK,CAAC;EACzB,IAAIC,MAAM,KAAK,GAAG,IAAIC,KAAK,KAAK,GAAG,EAAE,OAAO,IAAI;EAChD,IAAIV,QAAQ,CAACW,GAAG,CAACD,KAAK,CAAC,IAAIR,MAAM,CAACS,GAAG,CAACF,MAAM,CAAC,EAAE,OAAO,KAAK;EAC3D,MAAML,IAAI,GAAGG,IAAI,CAACK,UAAU,CAACJ,KAAK,GAAG,CAAC,CAAC;EACvC,IAAIH,eAAe,CAACD,IAAI,CAAC,EAAE,OAAO,KAAK;EACvC,OAAOD,MAAM,CAACC,IAAI,CAAC,IAAID,MAAM,CAACI,IAAI,CAACK,UAAU,CAACJ,KAAK,CAAC,CAAC;AACvD;;AAEA;AACA,OAAO,MAAMK,UAAU,CAAC;EACLC,MAAM,GAAG,IAAIC,GAAG,CAAiB,CAAC;EAClCC,IAAI,GAAG,IAAID,GAAG,CAAiB,CAAC;EAChCE,OAAO,GAAG,IAAIF,GAAG,CAA4B,CAAC;EACvDG,aAAa,GAAG,CAAC,CAAC;EAE1BC,WAAWA,CACQC,OAAiC,EACzCC,IAAY,EACrB;IAAA,KAFiBD,OAAiC,GAAjCA,OAAiC;IAAA,KACzCC,IAAY,GAAZA,IAAY;EACpB;;EAEH;EACAC,KAAKA,CAACf,IAAY,EAAU;IAC1B,IAAIe,KAAK,GAAG,IAAI,CAACR,MAAM,CAACS,GAAG,CAAChB,IAAI,CAAC;IACjC,IAAIe,KAAK,KAAKE,SAAS,EAAE;MACvBF,KAAK,GAAG,IAAI,CAACF,OAAO,CAACK,WAAW,CAAClB,IAAI,CAAC,CAACe,KAAK;MAC5C,IAAI,IAAI,CAACR,MAAM,CAACY,IAAI,GAAG3B,WAAW,EAAE,IAAI,CAACe,MAAM,CAACa,KAAK,CAAC,CAAC;MACvD,IAAI,CAACb,MAAM,CAACc,GAAG,CAACrB,IAAI,EAAEe,KAAK,CAAC;IAC9B;IACA,OAAOA,KAAK;EACd;;EAEA;EACAO,GAAGA,CAACtB,IAAY,EAAEuB,QAAgB,EAAU;IAC1C,IAAIA,QAAQ,IAAI,CAAC,IAAIvB,IAAI,KAAK,EAAE,EAAE,OAAO,EAAE;IAC3C;IACA,MAAMwB,MAAM,GAAGxB,IAAI,CAACyB,MAAM,GAAG,GAAG,GAAGzB,IAAI,CAAC0B,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG1B,IAAI;IAC5D,IAAIwB,MAAM,KAAKxB,IAAI,IAAI,IAAI,CAACe,KAAK,CAACf,IAAI,CAAC,IAAIuB,QAAQ,EAAE,OAAOvB,IAAI;IAChE,MAAM2B,GAAG,GAAG,GAAGC,IAAI,CAACC,KAAK,CAACN,QAAQ,CAAC,SAASC,MAAM,EAAE;IACpD,MAAMM,MAAM,GAAG,IAAI,CAACrB,IAAI,CAACO,GAAG,CAACW,GAAG,CAAC;IACjC,IAAIG,MAAM,KAAKb,SAAS,EAAE,OAAOa,MAAM;IACvC,IAAI,IAAI,CAACnB,aAAa,GAAG,CAAC,EAAE,IAAI,CAACA,aAAa,GAAG,IAAI,CAACE,OAAO,CAACK,WAAW,CAAC3B,QAAQ,CAAC,CAACwB,KAAK;IACzF,IAAIgB,MAAM,GAAG,EAAE;IACf,IAAI,IAAI,CAACpB,aAAa,IAAIY,QAAQ,EAAE;MAClC,MAAMS,IAAI,GAAG,IAAI,CAACnB,OAAO,CAACK,WAAW,CAACM,MAAM,CAAC,CAACT,KAAK;MACnD,IAAIkB,GAAG,GAAG,CAAC;MACX,IAAIC,IAAI,GAAGN,IAAI,CAACO,GAAG,CAACX,MAAM,CAACC,MAAM,EAAEG,IAAI,CAACQ,IAAI,CAAEZ,MAAM,CAACC,MAAM,GAAGF,QAAQ,GAAIK,IAAI,CAACS,GAAG,CAAC,CAAC,EAAEL,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;MACjG,OAAOC,GAAG,GAAGC,IAAI,EAAE;QACjB,MAAMI,MAAM,GAAIL,GAAG,GAAGC,IAAI,GAAG,CAAC,IAAK,CAAC;QACpC,IAAI,IAAI,CAACrB,OAAO,CAACK,WAAW,CAACM,MAAM,CAACE,KAAK,CAAC,CAAC,EAAEY,MAAM,CAAC,CAAC,CAACvB,KAAK,GAAG,IAAI,CAACJ,aAAa,IAAIY,QAAQ,EAAEU,GAAG,GAAGK,MAAM,CAAC,KACtGJ,IAAI,GAAGI,MAAM,GAAG,CAAC;MACxB;MACA;MACA,MAAMzC,IAAI,GAAG2B,MAAM,CAACnB,UAAU,CAAC4B,GAAG,GAAG,CAAC,CAAC;MACvC,IAAIA,GAAG,GAAG,CAAC,IAAIpC,IAAI,IAAI,MAAM,IAAIA,IAAI,IAAI,MAAM,EAAEoC,GAAG,EAAE;MACtDF,MAAM,GAAG,GAAGP,MAAM,CAACE,KAAK,CAAC,CAAC,EAAEO,GAAG,CAAC,GAAG1C,QAAQ,EAAE;IAC/C;IACA,IAAI,IAAI,CAACkB,IAAI,CAACU,IAAI,GAAG3B,WAAW,EAAE,IAAI,CAACiB,IAAI,CAACW,KAAK,CAAC,CAAC;IACnD,IAAI,CAACX,IAAI,CAACY,GAAG,CAACM,GAAG,EAAEI,MAAM,CAAC;IAC1B,OAAOA,MAAM;EACf;;EAEA;AACF;AACA;AACA;AACA;EACEQ,KAAKA,CAACvC,IAAY,EAAEuB,QAAgB,EAAEiB,QAAgB,EAAqB;IACzE,IAAIjB,QAAQ,IAAI,CAAC,IAAIiB,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE;IAC5C,MAAMhB,MAAM,GAAGxB,IAAI,CAACyC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IACvC,IAAIjB,MAAM,KAAK,EAAE,EAAE,OAAO,EAAE;IAC5B,MAAMG,GAAG,GAAG,GAAGC,IAAI,CAACC,KAAK,CAACN,QAAQ,CAAC,SAASiB,QAAQ,SAAShB,MAAM,EAAE;IACrE,MAAMM,MAAM,GAAG,IAAI,CAACpB,OAAO,CAACM,GAAG,CAACW,GAAG,CAAC;IACpC,IAAIG,MAAM,KAAKb,SAAS,EAAE,OAAOa,MAAM;IACvC,MAAMC,MAAgB,GAAG,EAAE;IAC3B,MAAMW,UAAU,GAAGlB,MAAM,CAACmB,KAAK,CAAC,IAAI,CAAC;IACrC;IACA,IAAIC,IAAI,GAAG,EAAE;IACb,IAAIC,GAAG,GAAG,KAAK;IACf,IAAIC,IAAI,GAAG,KAAK;IAChB,KAAK,MAAMC,SAAS,IAAIL,UAAU,EAAE;MAClC,IAAIX,MAAM,CAACN,MAAM,KAAKe,QAAQ,EAAE;QAC9BM,IAAI,GAAG,IAAI;QACX;MACF;MACA,IAAIE,IAAI,GAAGD,SAAS;MACpB,GAAG;QACD,IAAIhB,MAAM,CAACN,MAAM,KAAKe,QAAQ,EAAE;UAC9BM,IAAI,GAAGD,GAAG,GAAG,IAAI;UACjB;QACF;QACAD,IAAI,GAAGI,IAAI;QACX,MAAMC,GAAG,GAAG,IAAI,CAACC,OAAO,CAACF,IAAI,EAAEzB,QAAQ,CAAC;QACxCQ,MAAM,CAACoB,IAAI,CAACH,IAAI,CAACtB,KAAK,CAAC,CAAC,EAAEuB,GAAG,CAAC,CAACR,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClDO,IAAI,GAAGA,IAAI,CAACtB,KAAK,CAACuB,GAAG,CAAC,CAACR,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;MAC3C,CAAC,QAAQO,IAAI,KAAK,EAAE;MACpB,IAAIF,IAAI,EAAE;IACZ;IACA,IAAIA,IAAI,EAAE;MACR,MAAM7C,KAAK,GAAG8B,MAAM,CAACN,MAAM,GAAG,CAAC;MAC/BM,MAAM,CAAC9B,KAAK,CAAC,GAAG,IAAI,CAACqB,GAAG,CAACuB,GAAG,GAAGD,IAAI,GAAG,GAAGb,MAAM,CAAC9B,KAAK,CAAC,GAAGV,QAAQ,EAAE,EAAEgC,QAAQ,CAAC;IAChF;IACA,IAAI,IAAI,CAACb,OAAO,CAACS,IAAI,GAAG3B,WAAW,EAAE,IAAI,CAACkB,OAAO,CAACU,KAAK,CAAC,CAAC;IACzD,IAAI,CAACV,OAAO,CAACW,GAAG,CAACM,GAAG,EAAEI,MAAM,CAAC;IAC7B,OAAOA,MAAM;EACf;;EAEA;EACQmB,OAAOA,CAAClD,IAAY,EAAEuB,QAAgB,EAAE;IAC9C,IAAIvB,IAAI,KAAK,EAAE,IAAI,IAAI,CAACe,KAAK,CAACf,IAAI,CAAC,IAAIuB,QAAQ,EAAE,OAAOvB,IAAI,CAACyB,MAAM;IACnE;IACA,IAAIQ,GAAG,GAAG,CAAC;IACX,IAAIC,IAAI,GAAGN,IAAI,CAACO,GAAG,CAACnC,IAAI,CAACyB,MAAM,EAAEG,IAAI,CAACQ,IAAI,CAACb,QAAQ,CAAC,CAAC;IACrD,OAAOU,GAAG,GAAGC,IAAI,EAAE;MACjB,MAAMI,MAAM,GAAIL,GAAG,GAAGC,IAAI,GAAG,CAAC,IAAK,CAAC;MACpC,IAAI,IAAI,CAACrB,OAAO,CAACK,WAAW,CAAClB,IAAI,CAAC0B,KAAK,CAAC,CAAC,EAAEY,MAAM,CAAC,CAAC,CAACvB,KAAK,IAAIQ,QAAQ,EAAEU,GAAG,GAAGK,MAAM,CAAC,KAC/EJ,IAAI,GAAGI,MAAM,GAAG,CAAC;IACxB;IACA,KAAK,IAAIrC,KAAK,GAAGgC,GAAG,EAAEhC,KAAK,GAAG,CAAC,EAAEA,KAAK,EAAE,EAAE,IAAIF,QAAQ,CAACC,IAAI,EAAEC,KAAK,CAAC,EAAE,OAAOA,KAAK;IACjF;IACA,IAAIgD,GAAG,GAAGrB,IAAI,CAACS,GAAG,CAAC,CAAC,EAAEJ,GAAG,CAAC;IAC1B,IAAIgB,GAAG,GAAGjD,IAAI,CAACyB,MAAM,IAAI3B,eAAe,CAACE,IAAI,CAACK,UAAU,CAAC4C,GAAG,GAAG,CAAC,CAAC,CAAC,EAAEA,GAAG,GAAGA,GAAG,GAAG,CAAC,GAAGA,GAAG,GAAG,CAAC,GAAGA,GAAG,GAAG,CAAC;IACrG,OAAOA,GAAG;EACZ;AACF","ignoreList":[]}
@@ -5,6 +5,8 @@ export interface GridTheme {
5
5
  smallFont: string;
6
6
  fontSize: number;
7
7
  fontFamily: string;
8
+ /** Height of each further line of wrapped cell text, in pixels. */
9
+ lineHeight: number;
8
10
  background: string;
9
11
  text: string;
10
12
  muted: string;
@@ -20,10 +22,16 @@ export interface GridTheme {
20
22
  selectionBorder: string;
21
23
  activeBorder: string;
22
24
  accent: string;
25
+ /** Text and marks drawn on `accent`, such as the check of a checkbox. */
26
+ accentText: string;
27
+ /** Background of checked rows. */
28
+ checkedRow: string;
23
29
  nullText: string;
24
30
  placeholder: string;
25
31
  match: string;
26
32
  error: string;
33
+ /** Text of cells whose `cellAction` is a link. */
34
+ link: string;
27
35
  }
28
36
  /** Resolves the theme of `root`. Colors given as `light-dark()` or system colors resolve to concrete values. */
29
37
  export declare function resolveTheme(root: HTMLElement): GridTheme;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/canvas/theme.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AA8BD,gHAAgH;AAChH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,CA8BzD;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAG3E"}
@@ -0,0 +1,62 @@
1
+ /** Colors and fonts for the canvas, read from the CSS custom properties of the grid's root element. */
2
+
3
+ const colorTokens = {
4
+ background: "--vg-bg",
5
+ text: "--vg-fg",
6
+ muted: "--vg-muted",
7
+ headerBackground: "--vg-header-bg",
8
+ headerText: "--vg-header-fg",
9
+ headerActive: "--vg-header-active-bg",
10
+ gutterBackground: "--vg-gutter-bg",
11
+ gutterText: "--vg-gutter-fg",
12
+ gutterViewText: "--vg-gutter-view-fg",
13
+ line: "--vg-line",
14
+ lineStrong: "--vg-line-strong",
15
+ selection: "--vg-selection-bg",
16
+ selectionBorder: "--vg-selection-border",
17
+ activeBorder: "--vg-active-border",
18
+ accent: "--vg-accent",
19
+ accentText: "--vg-accent-fg",
20
+ checkedRow: "--vg-checked-row-bg",
21
+ nullText: "--vg-null-fg",
22
+ placeholder: "--vg-placeholder",
23
+ match: "--vg-match-bg",
24
+ error: "--vg-error-fg",
25
+ link: "--vg-link-fg"
26
+ };
27
+
28
+ /** Resolves the theme of `root`. Colors given as `light-dark()` or system colors resolve to concrete values. */
29
+ export function resolveTheme(root) {
30
+ const probe = document.createElement("span");
31
+ probe.style.display = "none";
32
+ root.appendChild(probe);
33
+ try {
34
+ const color = token => {
35
+ probe.style.color = `var(${token})`;
36
+ return getComputedStyle(probe).color;
37
+ };
38
+ const style = getComputedStyle(root);
39
+ const fontFamily = style.getPropertyValue("--vg-font-family").trim() || style.fontFamily || "system-ui, sans-serif";
40
+ const fontSize = Number.parseFloat(style.getPropertyValue("--vg-font-size")) || Number.parseFloat(style.fontSize) || 13;
41
+ const lineHeight = Number.parseFloat(style.getPropertyValue("--vg-line-height")) || Math.round(fontSize * 1.4);
42
+ const colors = Object.fromEntries(Object.entries(colorTokens).map(([key, token]) => [key, color(token)]));
43
+ return {
44
+ ...colors,
45
+ fontFamily,
46
+ fontSize,
47
+ lineHeight,
48
+ font: `${fontSize}px ${fontFamily}`,
49
+ headerFont: `600 ${fontSize}px ${fontFamily}`,
50
+ smallFont: `${Math.max(9, fontSize - 2)}px ${fontFamily}`
51
+ };
52
+ } finally {
53
+ probe.remove();
54
+ }
55
+ }
56
+
57
+ /** Reads a length custom property in pixels, or `fallback`. */
58
+ export function cssLength(root, token, fallback) {
59
+ const value = Number.parseFloat(getComputedStyle(root).getPropertyValue(token));
60
+ return Number.isFinite(value) && value > 0 ? value : fallback;
61
+ }
62
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["colorTokens","background","text","muted","headerBackground","headerText","headerActive","gutterBackground","gutterText","gutterViewText","line","lineStrong","selection","selectionBorder","activeBorder","accent","accentText","checkedRow","nullText","placeholder","match","error","link","resolveTheme","root","probe","document","createElement","style","display","appendChild","color","token","getComputedStyle","fontFamily","getPropertyValue","trim","fontSize","Number","parseFloat","lineHeight","Math","round","colors","Object","fromEntries","entries","map","key","font","headerFont","smallFont","max","remove","cssLength","fallback","value","isFinite"],"sources":["theme.ts"],"sourcesContent":["/** Colors and fonts for the canvas, read from the CSS custom properties of the grid's root element. */\nexport interface GridTheme {\n font: string;\n headerFont: string;\n smallFont: string;\n fontSize: number;\n fontFamily: string;\n /** Height of each further line of wrapped cell text, in pixels. */\n lineHeight: number;\n background: string;\n text: string;\n muted: string;\n headerBackground: string;\n headerText: string;\n headerActive: string;\n gutterBackground: string;\n gutterText: string;\n gutterViewText: string;\n line: string;\n lineStrong: string;\n selection: string;\n selectionBorder: string;\n activeBorder: string;\n accent: string;\n /** Text and marks drawn on `accent`, such as the check of a checkbox. */\n accentText: string;\n /** Background of checked rows. */\n checkedRow: string;\n nullText: string;\n placeholder: string;\n match: string;\n error: string;\n /** Text of cells whose `cellAction` is a link. */\n link: string;\n}\n\nconst colorTokens: Record<\n keyof Omit<GridTheme, \"font\" | \"headerFont\" | \"smallFont\" | \"fontSize\" | \"fontFamily\" | \"lineHeight\">,\n string\n> = {\n background: \"--vg-bg\",\n text: \"--vg-fg\",\n muted: \"--vg-muted\",\n headerBackground: \"--vg-header-bg\",\n headerText: \"--vg-header-fg\",\n headerActive: \"--vg-header-active-bg\",\n gutterBackground: \"--vg-gutter-bg\",\n gutterText: \"--vg-gutter-fg\",\n gutterViewText: \"--vg-gutter-view-fg\",\n line: \"--vg-line\",\n lineStrong: \"--vg-line-strong\",\n selection: \"--vg-selection-bg\",\n selectionBorder: \"--vg-selection-border\",\n activeBorder: \"--vg-active-border\",\n accent: \"--vg-accent\",\n accentText: \"--vg-accent-fg\",\n checkedRow: \"--vg-checked-row-bg\",\n nullText: \"--vg-null-fg\",\n placeholder: \"--vg-placeholder\",\n match: \"--vg-match-bg\",\n error: \"--vg-error-fg\",\n link: \"--vg-link-fg\",\n};\n\n/** Resolves the theme of `root`. Colors given as `light-dark()` or system colors resolve to concrete values. */\nexport function resolveTheme(root: HTMLElement): GridTheme {\n const probe = document.createElement(\"span\");\n probe.style.display = \"none\";\n root.appendChild(probe);\n try {\n const color = (token: string) => {\n probe.style.color = `var(${token})`;\n return getComputedStyle(probe).color;\n };\n const style = getComputedStyle(root);\n const fontFamily = style.getPropertyValue(\"--vg-font-family\").trim() || style.fontFamily || \"system-ui, sans-serif\";\n const fontSize =\n Number.parseFloat(style.getPropertyValue(\"--vg-font-size\")) || Number.parseFloat(style.fontSize) || 13;\n const lineHeight = Number.parseFloat(style.getPropertyValue(\"--vg-line-height\")) || Math.round(fontSize * 1.4);\n const colors = Object.fromEntries(Object.entries(colorTokens).map(([key, token]) => [key, color(token)])) as Pick<\n GridTheme,\n keyof typeof colorTokens\n >;\n return {\n ...colors,\n fontFamily,\n fontSize,\n lineHeight,\n font: `${fontSize}px ${fontFamily}`,\n headerFont: `600 ${fontSize}px ${fontFamily}`,\n smallFont: `${Math.max(9, fontSize - 2)}px ${fontFamily}`,\n };\n } finally {\n probe.remove();\n }\n}\n\n/** Reads a length custom property in pixels, or `fallback`. */\nexport function cssLength(root: HTMLElement, token: string, fallback: number) {\n const value = Number.parseFloat(getComputedStyle(root).getPropertyValue(token));\n return Number.isFinite(value) && value > 0 ? value : fallback;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,48 @@
1
+ import type { JsonValue, LoadedRow } from "vastgrid-spec";
2
+ /** Rows in a block of the cache: reads cover whole blocks. */
3
+ export declare const BLOCK_ROWS = 256;
4
+ /** A read of rows `[start, end)` of a view, for some of its columns. */
5
+ export interface Read {
6
+ start: number;
7
+ end: number;
8
+ columns: string[];
9
+ }
10
+ /**
11
+ * The rows of one view that the store has read, in blocks of `BLOCK_ROWS` rows, with a budget of bytes beyond
12
+ * which the blocks used least recently leave (§4.1 of react.md: rows are not in snapshots).
13
+ */
14
+ export declare class ViewCache {
15
+ private readonly blocks;
16
+ private clock;
17
+ /** Bytes the blocks take, roughly. */
18
+ bytes: number;
19
+ /** Changes whenever rows arrive or leave. */
20
+ version: number;
21
+ private block;
22
+ private ensure;
23
+ /** The value of a cell; undefined while it is not read. */
24
+ value(row: number, column: string): JsonValue | undefined;
25
+ /** Whether the engine cut the value of a cell to the text limit, so that the grid shows that it goes on. */
26
+ isCut(row: number, column: string): boolean;
27
+ /** The row ID of a row; undefined while it is not read or in a view without row IDs. */
28
+ rowId(row: number): number | undefined;
29
+ /** A row as commands read it (§6.1): its key and its values, or undefined while it is not read. */
30
+ loaded(row: number, rowKey: string | undefined): LoadedRow | undefined;
31
+ /**
32
+ * What to read so that rows `[start, end)` have `columns`: reads of runs of blocks that lack the same columns,
33
+ * each of at most `maxCells` cells, leaving out what is read or being read.
34
+ */
35
+ reads(start: number, end: number, columns: readonly string[], rowCount: number, maxCells?: number): Read[];
36
+ /** Marks the columns of a read as being read, or no longer. */
37
+ reading(read: Read, on: boolean): void;
38
+ /**
39
+ * Takes the rows of a read, which starts at a block: `rows` holds the values of `columns` for rows `start` to
40
+ * `start + rows.length`.
41
+ */
42
+ receive(start: number, rowIds: number[] | null, columns: readonly string[], rows: readonly (readonly JsonValue[])[], cut: Record<string, number[]> | undefined): void;
43
+ /** Marks the blocks of rows `[start, end)` as used now, so that they leave last. */
44
+ touch(start: number, end: number): void;
45
+ /** Removes the blocks used least recently until the cache fits `budget` bytes, keeping rows `[start, end)`. */
46
+ evict(budget: number, start: number, end: number): void;
47
+ }
48
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAElE,8DAA8D;AAC9D,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,wEAAwE;AACxE,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAwBD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,KAAK,CAAK;IAClB,sCAAsC;IACtC,KAAK,SAAK;IACV,6CAA6C;IAC7C,OAAO,SAAK;IAEZ,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,MAAM;IAkBd,2DAA2D;IAC3D,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAKxD;IAED,4GAA4G;IAC5G,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG1C;IAED,wFAAwF;IACxF,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIrC;IAED,mGAAmG;IACnG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAoBrE;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,SAAU,GAAG,IAAI,EAAE,CAwC1G;IAED,+DAA+D;IAC/D,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,QAQ9B;IAED;;;OAGG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EACvB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,EACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,QA0C1C;IAED,oFAAoF;IACpF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAM/B;IAED,+GAA+G;IAC/G,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAa/C;CACF"}