@react-x11/components 0.11.0 → 0.12.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 (100) hide show
  1. package/dist/flow/node.d.ts +14 -6
  2. package/dist/flow/node.d.ts.map +1 -1
  3. package/dist/flow/node.js +82 -64
  4. package/dist/flow/node.js.map +1 -1
  5. package/dist/html/controls.d.ts +26 -7
  6. package/dist/html/controls.d.ts.map +1 -1
  7. package/dist/html/controls.js +28 -3
  8. package/dist/html/controls.js.map +1 -1
  9. package/dist/html/css/cascade.d.ts.map +1 -1
  10. package/dist/html/css/cascade.js +19 -6
  11. package/dist/html/css/cascade.js.map +1 -1
  12. package/dist/html/css/color.d.ts +19 -0
  13. package/dist/html/css/color.d.ts.map +1 -1
  14. package/dist/html/css/color.js +86 -0
  15. package/dist/html/css/color.js.map +1 -1
  16. package/dist/html/css/parse.d.ts +11 -0
  17. package/dist/html/css/parse.d.ts.map +1 -1
  18. package/dist/html/css/parse.js +114 -4
  19. package/dist/html/css/parse.js.map +1 -1
  20. package/dist/html/css/style.d.ts +38 -1
  21. package/dist/html/css/style.d.ts.map +1 -1
  22. package/dist/html/css/style.js +326 -8
  23. package/dist/html/css/style.js.map +1 -1
  24. package/dist/html/css/ua.js +14 -0
  25. package/dist/html/css/ua.js.map +1 -1
  26. package/dist/html/css/values.d.ts +10 -1
  27. package/dist/html/css/values.d.ts.map +1 -1
  28. package/dist/html/css/values.js +27 -2
  29. package/dist/html/css/values.js.map +1 -1
  30. package/dist/html/css/vars.d.ts +5 -0
  31. package/dist/html/css/vars.d.ts.map +1 -1
  32. package/dist/html/css/vars.js +2 -2
  33. package/dist/html/css/vars.js.map +1 -1
  34. package/dist/html/dom.d.ts.map +1 -1
  35. package/dist/html/dom.js +35 -2
  36. package/dist/html/dom.js.map +1 -1
  37. package/dist/html/index.d.ts.map +1 -1
  38. package/dist/html/index.js +38 -1
  39. package/dist/html/index.js.map +1 -1
  40. package/dist/html/layout/block.d.ts +11 -2
  41. package/dist/html/layout/block.d.ts.map +1 -1
  42. package/dist/html/layout/block.js +181 -18
  43. package/dist/html/layout/block.js.map +1 -1
  44. package/dist/html/layout/boxes.d.ts +34 -6
  45. package/dist/html/layout/boxes.d.ts.map +1 -1
  46. package/dist/html/layout/boxes.js +35 -14
  47. package/dist/html/layout/boxes.js.map +1 -1
  48. package/dist/html/layout/cache.d.ts +2 -2
  49. package/dist/html/layout/cache.d.ts.map +1 -1
  50. package/dist/html/layout/cache.js +8 -3
  51. package/dist/html/layout/cache.js.map +1 -1
  52. package/dist/html/layout/floats.d.ts +4 -0
  53. package/dist/html/layout/floats.d.ts.map +1 -1
  54. package/dist/html/layout/floats.js +26 -0
  55. package/dist/html/layout/floats.js.map +1 -1
  56. package/dist/html/layout/inline.d.ts +26 -2
  57. package/dist/html/layout/inline.d.ts.map +1 -1
  58. package/dist/html/layout/inline.js +1222 -115
  59. package/dist/html/layout/inline.js.map +1 -1
  60. package/dist/html/node.d.ts +33 -0
  61. package/dist/html/node.d.ts.map +1 -1
  62. package/dist/html/node.js +512 -51
  63. package/dist/html/node.js.map +1 -1
  64. package/dist/html/paint.d.ts +53 -1
  65. package/dist/html/paint.d.ts.map +1 -1
  66. package/dist/html/paint.js +546 -180
  67. package/dist/html/paint.js.map +1 -1
  68. package/dist/html/surfaces.d.ts +7 -2
  69. package/dist/html/surfaces.d.ts.map +1 -1
  70. package/dist/html/surfaces.js +16 -0
  71. package/dist/html/surfaces.js.map +1 -1
  72. package/dist/internal/window.d.ts +22 -0
  73. package/dist/internal/window.d.ts.map +1 -1
  74. package/dist/internal/window.js +35 -8
  75. package/dist/internal/window.js.map +1 -1
  76. package/dist/richtext/node.d.ts +7 -0
  77. package/dist/richtext/node.d.ts.map +1 -1
  78. package/dist/richtext/node.js.map +1 -1
  79. package/package.json +5 -3
  80. package/src/flow/node.ts +80 -64
  81. package/src/html/controls.ts +50 -9
  82. package/src/html/css/cascade.ts +19 -6
  83. package/src/html/css/color.ts +87 -0
  84. package/src/html/css/parse.ts +107 -4
  85. package/src/html/css/style.ts +343 -8
  86. package/src/html/css/ua.ts +14 -0
  87. package/src/html/css/values.ts +31 -3
  88. package/src/html/css/vars.ts +2 -2
  89. package/src/html/dom.ts +38 -2
  90. package/src/html/index.ts +39 -1
  91. package/src/html/layout/block.ts +228 -16
  92. package/src/html/layout/boxes.ts +55 -21
  93. package/src/html/layout/cache.ts +8 -3
  94. package/src/html/layout/floats.ts +24 -0
  95. package/src/html/layout/inline.ts +1435 -108
  96. package/src/html/node.ts +535 -54
  97. package/src/html/paint.ts +650 -241
  98. package/src/html/surfaces.ts +21 -1
  99. package/src/internal/window.ts +36 -8
  100. package/src/richtext/node.ts +7 -0
@@ -8,7 +8,7 @@
8
8
  import { Surface } from 'react-x11/ntk';
9
9
 
10
10
  /** ntk's `Surface`, as this uses it. */
11
- interface SurfaceLike {
11
+ export interface SurfaceLike {
12
12
  getContext(kind: '2d'): unknown;
13
13
  destroy?(): void;
14
14
  }
@@ -18,6 +18,26 @@ interface Kept {
18
18
  pixels: number;
19
19
  }
20
20
 
21
+ /**
22
+ * A transparent surface of its own, the caller's to destroy once drawn: a
23
+ * masked element is drawn on one and composited. Null where the backend
24
+ * has no offscreen surface — the headless mock.
25
+ */
26
+ export function newSurface(
27
+ app: unknown,
28
+ width: number,
29
+ height: number,
30
+ ): SurfaceLike | null {
31
+ try {
32
+ return new Surface(app as never, {
33
+ width,
34
+ height,
35
+ }) as unknown as SurfaceLike;
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+
21
41
  /**
22
42
  * Surfaces by key, the least recently drawn given up first once they hold
23
43
  * more than `budget` pixels. One too large for a quarter of the budget is
@@ -99,6 +99,34 @@ const VEL_GAP_MS = 250;
99
99
  * settle. */
100
100
  const FAST_V = 1.5;
101
101
 
102
+ /**
103
+ * The window's time and its timer: what a scroll's speed is measured with,
104
+ * and what decides it has stopped (`IDLE_MS`) and paces the band's growth
105
+ * after it (`GROW_MS`). A test holds both (`holdClock` in
106
+ * test/held-clock.ts). On the real clock a runner that spends longer than
107
+ * `IDLE_MS` over one step of a flick ends the flick there, and the settle
108
+ * that follows measures the rows and moves the scroll by what they
109
+ * measured — outside the `act` the step ran in, so a look at the rows finds
110
+ * the new offset against the layout before it, every row a few pixels off.
111
+ * A test of a flick cannot tell that from rows that moved.
112
+ *
113
+ * Not the catch-up's clock: `catchupSince` is epoch milliseconds, which a
114
+ * scroll hint is handed as `since`. The shape of the map's `glideClock`,
115
+ * and exported from this module only, which has no subpath: this is for
116
+ * the tests.
117
+ */
118
+ export const windowClock = {
119
+ now(): number {
120
+ return Date.now();
121
+ },
122
+ arm(step: () => void, ms: number): DelayTick {
123
+ return later(step, ms);
124
+ },
125
+ disarm(handle: DelayTick): void {
126
+ cancelLater(handle);
127
+ },
128
+ };
129
+
102
130
  /** More rows than this entering the window in one render is a flood — a
103
131
  * teleport or a hard flick — and floods build skeletons first. An ordinary
104
132
  * notch brings in a handful and never trips this. */
@@ -302,7 +330,7 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
302
330
  // estimate adaptation) runs on.
303
331
  bump((n) => n + 1);
304
332
  if (wantsGrowth.current) {
305
- idleTimer.current = later(tick, GROW_MS);
333
+ idleTimer.current = windowClock.arm(tick, GROW_MS);
306
334
  }
307
335
  }, []);
308
336
 
@@ -312,7 +340,7 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
312
340
  // one has no slice to rebuild, and re-rendering it on a scroll it
313
341
  // already drew would be work for nothing.
314
342
  if (!inp.current.virtualizing) return;
315
- const now = Date.now();
343
+ const now = windowClock.now();
316
344
  const s = vel.current;
317
345
  const dt = now - s.t;
318
346
  if (dt > 0 && dt < VEL_GAP_MS) {
@@ -325,8 +353,8 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
325
353
  s.t = now;
326
354
  s.top = top;
327
355
  active.current = true;
328
- cancelLater(idleTimer.current);
329
- idleTimer.current = later(tick, IDLE_MS);
356
+ windowClock.disarm(idleTimer.current);
357
+ idleTimer.current = windowClock.arm(tick, IDLE_MS);
330
358
  setView((prev) => (prev.top === top ? prev : { ...prev, top }));
331
359
  },
332
360
  [tick],
@@ -365,13 +393,13 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
365
393
  // idle delay to fill them in would be a visible pause.
366
394
  useEffect(() => {
367
395
  if (hasSkeletons.current) {
368
- cancelLater(idleTimer.current);
369
- idleTimer.current = later(tick, GROW_MS);
396
+ windowClock.disarm(idleTimer.current);
397
+ idleTimer.current = windowClock.arm(tick, GROW_MS);
370
398
  } else if (wantsGrowth.current && idleTimer.current === null) {
371
- idleTimer.current = later(tick, IDLE_MS);
399
+ idleTimer.current = windowClock.arm(tick, IDLE_MS);
372
400
  }
373
401
  });
374
- useEffect(() => () => cancelLater(idleTimer.current), []);
402
+ useEffect(() => () => windowClock.disarm(idleTimer.current), []);
375
403
 
376
404
  const {
377
405
  heights,
@@ -129,6 +129,13 @@ export interface TextRun {
129
129
  * either side of an inline box's margin, border or padding. ntk's, from
130
130
  * 8.14.2. */
131
131
  shapeApart?: boolean;
132
+ /** Kerned with the runs either side of it though its letter spacing is
133
+ * not theirs: the spacing a justified line or `word-spacing` gives a
134
+ * space is in addition to kerning and no element's (CSS Text 3, 7.2,
135
+ * 7.3), where a run of an element's own letter spacing is shaped apart,
136
+ * as a browser shapes it. ntk's, from 8.15.0; CoreText takes a spaced
137
+ * glyph's spacing in place of its pairs either way. */
138
+ kernAcross?: boolean;
132
139
  }
133
140
 
134
141
  /** The props `<richtext>` takes. */