flexdesk 0.6.2 → 0.6.3

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.
package/dist/flow.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-6NG7YVBG.js";
4
4
  import {
5
5
  DataTable
6
- } from "./chunk-CPYBQN3Q.js";
6
+ } from "./chunk-WLASPRGP.js";
7
7
  import "./chunk-6JSOVNID.js";
8
8
  import "./chunk-FL5KFNQH.js";
9
9
  import {
package/dist/tiles.js CHANGED
@@ -16,8 +16,8 @@ import {
16
16
  } from "./chunk-O5OHMWBB.js";
17
17
  import {
18
18
  openRawTracesWindow
19
- } from "./chunk-XYUZF5CD.js";
20
- import "./chunk-CPYBQN3Q.js";
19
+ } from "./chunk-WAVLVXYV.js";
20
+ import "./chunk-WLASPRGP.js";
21
21
  import "./chunk-6JSOVNID.js";
22
22
  import "./chunk-FL5KFNQH.js";
23
23
  import {
package/dist/widgets.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  parseDateValue,
36
36
  parseDuration,
37
37
  resolvePaging
38
- } from "./chunk-CPYBQN3Q.js";
38
+ } from "./chunk-WLASPRGP.js";
39
39
  import {
40
40
  ManagedWindow,
41
41
  ROW_CONTROL_SELECTOR,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flexdesk",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "A tiling window manager and widget set for desktop-class web applications. Zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1088,7 +1088,12 @@ export class DataTable {
1088
1088
  // body's auto layout, then we lock both tables to those widths
1089
1089
  // via table-layout:fixed + explicit cell widths.
1090
1090
  if (this._headerTableEl && this._tableEl) {
1091
- requestAnimationFrame(() => this._syncHeaderWidths());
1091
+ // 0.6.3: and once the widths are fixed the rows may be another
1092
+ // height than they were measured at — so the window measures again.
1093
+ requestAnimationFrame(() => {
1094
+ this._syncHeaderWidths();
1095
+ this._virtRemeasure();
1096
+ });
1092
1097
  // Re-sync on container resize so columns stay aligned when
1093
1098
  // the parent flex / grid layout changes (window resize,
1094
1099
  // splitter drag, etc.).
@@ -2695,26 +2700,52 @@ export class DataTable {
2695
2700
  return lo;
2696
2701
  }
2697
2702
 
2698
- /** Measure one real row. Client pixels, so the zoom is divided back out —
2699
- * `_measureNaturalWidths` explains why — and NOT `offsetHeight`, which is
2700
- * rounded: 21 for a 21.19px row is a 1,100px error over 6,000 rows. */
2703
+ /**
2704
+ * Measure the rows that are DRAWN — the median of up to 64 of them. Client
2705
+ * pixels, so the zoom is divided back out (`_measureNaturalWidths` explains
2706
+ * why), and NOT `offsetHeight`, which is rounded: 21 for a 21.19px row is a
2707
+ * 1,100px error over 6,000 rows.
2708
+ *
2709
+ * 0.6.3: IT USED TO MEASURE ONE ROW, ONCE, AT RENDER, and trust it for the
2710
+ * life of the table. A row measured at a bad moment — a box not yet laid
2711
+ * out at its width, a font not yet loaded — set every row's height: a
2712
+ * Tables grid drawing 22.8px rows was found holding a 134px estimate, so the
2713
+ * window took a 650px viewport for five rows, drew rows 1–35 and left the
2714
+ * rest of the box blank spacer while the reader scrolled. Now it is asked
2715
+ * again on every window update (`_virtUpdate`), on a resize and once the
2716
+ * column widths are fixed, and corrects itself the first time real rows
2717
+ * are on screen. The first measure is exact; after that a change has to be
2718
+ * larger than half a pixel, so rows of mixed heights cannot make the
2719
+ * offsets move under the reader on every scroll.
2720
+ *
2721
+ * @returns {boolean} whether the heights changed (the offsets are recomputed).
2722
+ */
2701
2723
  _virtMeasure() {
2702
2724
  const v = this._virt;
2703
2725
  if (!v) return false;
2726
+ const zoom = this._tableEl?.currentCSSZoom || 1;
2727
+ const heights = [];
2704
2728
  for (const tr of v.map.values()) {
2705
2729
  if (!tr.isConnected || tr.hidden) continue;
2706
- const zoom = this._tableEl?.currentCSSZoom || 1;
2707
2730
  const h = tr.getBoundingClientRect().height / zoom;
2708
- if (!(h > 0)) return false;
2709
- if (Math.abs(h - v.base) > 0.01) {
2710
- v.base = h;
2711
- this._virtBase = h;
2712
- this._virtComputeOffsets();
2713
- return true;
2714
- }
2715
- return false;
2716
- }
2717
- return false;
2731
+ if (h > 0) heights.push(h);
2732
+ if (heights.length >= 64) break;
2733
+ }
2734
+ if (!heights.length) return false;
2735
+ heights.sort((a, b) => a - b);
2736
+ const h = heights[heights.length >> 1];
2737
+ const tolerance = v.measured ? 0.5 : 0.01;
2738
+ v.measured = true;
2739
+ if (Math.abs(h - v.base) <= tolerance) return false;
2740
+ v.base = h;
2741
+ this._virtBase = h;
2742
+ this._virtComputeOffsets();
2743
+ return true;
2744
+ }
2745
+
2746
+ /** Measure again, and redraw the window when the heights moved. */
2747
+ _virtRemeasure() {
2748
+ if (this._virtMeasure()) this._virtUpdate({ force: true });
2718
2749
  }
2719
2750
 
2720
2751
  /**
@@ -2734,9 +2765,12 @@ export class DataTable {
2734
2765
  * @param {number} [o.viewport] the viewport height, likewise.
2735
2766
  * @returns {HTMLElement[]} the rows added.
2736
2767
  */
2737
- _virtUpdate({ force = false, notify = true, top = null, viewport = null } = {}) {
2768
+ _virtUpdate({ force = false, notify = true, top = null, viewport = null, measure = true } = {}) {
2738
2769
  const v = this._virt;
2739
2770
  if (!v || !v.offsets) return [];
2771
+ // The rows on screen say how tall a row is — before the window is
2772
+ // placed, so a stale estimate is not used to place it (`_virtMeasure`).
2773
+ if (measure && this._virtMeasure()) force = true;
2740
2774
  const n = v.rows.length;
2741
2775
  const wrap = this._tableWrapEl;
2742
2776
  const view = viewport || wrap?.clientHeight || VIRTUAL_FALLBACK_VIEWPORT_PX;
@@ -2764,6 +2798,13 @@ export class DataTable {
2764
2798
  console.error('[DataTable] onRowsRendered threw', err);
2765
2799
  }
2766
2800
  }
2801
+ // And the rows just drawn: if they disagree with the estimate the
2802
+ // window was placed by, place it once more by what they say.
2803
+ if (measure && added.length && this._virtMeasure()) {
2804
+ return added.concat(this._virtUpdate({
2805
+ force: true, notify, top, viewport, measure: false,
2806
+ }));
2807
+ }
2767
2808
  }
2768
2809
  return added;
2769
2810
  }