flexdesk 0.4.3 → 0.4.5

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/README.md CHANGED
@@ -163,6 +163,28 @@ anywhere else, it walks the focused tile as before. With `backToOpenList`, a
163
163
  record in a window closes onto an open list of its section, first among the
164
164
  window's own tabs and then in any tile of its desktop.
165
165
 
166
+ ### Column sizing
167
+
168
+ `fitColumns(columns, avail)` (from `@flexdesk/widgets`) turns per-column
169
+ measurements into widths. Pass each column's widest cell (`natural`), the width
170
+ most cells fit (`typical`), the header label (`header`) and any user-dragged
171
+ width (`pinned`). Short columns such as ids, dates and statuses keep their full
172
+ values, and free-text columns (`text`, or anything 240px and wider) take the
173
+ rest. When space runs short, short columns lose their rare outliers first,
174
+ then text shrinks to a floor. The widths are fractional and add up to `avail`
175
+ exactly whenever the floors fit. `DataTable` does not use it yet; an embedder
176
+ that measures its own columns can.
177
+
178
+ ### Scrollbars
179
+
180
+ `installAutoScrollbars(root)` (from `@flexdesk/widgets`) replaces the browser's
181
+ scrollbars under `root` with thin overlay bars that show while an element is
182
+ hovered or scrolling and fade out afterwards. Native bars are hidden, so no
183
+ element reserves layout width for one. The overlay bars live in one fixed
184
+ layer, so a container that redraws its contents cannot lose its bar, and
185
+ textareas get one too. Containers that already use `installOverlayScrollbar`
186
+ keep their own.
187
+
166
188
  ## The host port
167
189
 
168
190
  FlexDesk never touches `pywebview`, `fetch`, `localStorage` or the filesystem. It
package/css/base.css CHANGED
@@ -4808,3 +4808,48 @@ button.twm-about-dialog__btn--close:focus {
4808
4808
  cursor: pointer;
4809
4809
  }
4810
4810
  .twm-zoom__value:hover { color: var(--text-primary); }
4811
+
4812
+ /* ══ AUTO SCROLLBARS ═════════════════════════════════════════════════
4813
+ *
4814
+ * `installAutoScrollbars(root)` (src/ui/utils/auto_scrollbars.js): no native
4815
+ * scrollbar under `root`, so nothing reserves layout width for one, and a thin
4816
+ * overlay bar in one fixed layer over every element that scrolls, shown while
4817
+ * it is hovered or scrolling and faded out after. */
4818
+ .twm-autoscroll,
4819
+ .twm-autoscroll * {
4820
+ scrollbar-width: none;
4821
+ }
4822
+ .twm-autoscroll::-webkit-scrollbar,
4823
+ .twm-autoscroll *::-webkit-scrollbar {
4824
+ width: 0;
4825
+ height: 0;
4826
+ }
4827
+ .twm-autoscroll-layer {
4828
+ position: fixed;
4829
+ inset: 0;
4830
+ pointer-events: none;
4831
+ z-index: 2147483000;
4832
+ }
4833
+ .twm-autoscroll-bar {
4834
+ position: fixed;
4835
+ border-radius: 3px;
4836
+ background: rgba(255, 255, 255, 0.06);
4837
+ opacity: 0;
4838
+ pointer-events: none;
4839
+ transition: opacity 160ms ease;
4840
+ }
4841
+ .twm-autoscroll-bar--on {
4842
+ opacity: 1;
4843
+ pointer-events: auto;
4844
+ }
4845
+ .twm-autoscroll-thumb {
4846
+ position: absolute;
4847
+ border-radius: 3px;
4848
+ background: rgba(255, 255, 255, 0.28);
4849
+ cursor: pointer;
4850
+ transition: background 80ms ease;
4851
+ }
4852
+ .twm-autoscroll-bar--on:hover .twm-autoscroll-thumb,
4853
+ .twm-autoscroll-bar--active .twm-autoscroll-thumb {
4854
+ background: rgba(255, 255, 255, 0.45);
4855
+ }
package/css/flexdesk.css CHANGED
@@ -7156,3 +7156,48 @@ tr:hover .twm-row-action { opacity: 1; }
7156
7156
  cursor: pointer;
7157
7157
  }
7158
7158
  .twm-zoom__value:hover { color: var(--text-primary); }
7159
+
7160
+ /* ══ AUTO SCROLLBARS ═════════════════════════════════════════════════
7161
+ *
7162
+ * `installAutoScrollbars(root)` (src/ui/utils/auto_scrollbars.js): no native
7163
+ * scrollbar under `root`, so nothing reserves layout width for one, and a thin
7164
+ * overlay bar in one fixed layer over every element that scrolls, shown while
7165
+ * it is hovered or scrolling and faded out after. */
7166
+ .twm-autoscroll,
7167
+ .twm-autoscroll * {
7168
+ scrollbar-width: none;
7169
+ }
7170
+ .twm-autoscroll::-webkit-scrollbar,
7171
+ .twm-autoscroll *::-webkit-scrollbar {
7172
+ width: 0;
7173
+ height: 0;
7174
+ }
7175
+ .twm-autoscroll-layer {
7176
+ position: fixed;
7177
+ inset: 0;
7178
+ pointer-events: none;
7179
+ z-index: 2147483000;
7180
+ }
7181
+ .twm-autoscroll-bar {
7182
+ position: fixed;
7183
+ border-radius: 3px;
7184
+ background: rgba(255, 255, 255, 0.06);
7185
+ opacity: 0;
7186
+ pointer-events: none;
7187
+ transition: opacity 160ms ease;
7188
+ }
7189
+ .twm-autoscroll-bar--on {
7190
+ opacity: 1;
7191
+ pointer-events: auto;
7192
+ }
7193
+ .twm-autoscroll-thumb {
7194
+ position: absolute;
7195
+ border-radius: 3px;
7196
+ background: rgba(255, 255, 255, 0.28);
7197
+ cursor: pointer;
7198
+ transition: background 80ms ease;
7199
+ }
7200
+ .twm-autoscroll-bar--on:hover .twm-autoscroll-thumb,
7201
+ .twm-autoscroll-bar--active .twm-autoscroll-thumb {
7202
+ background: rgba(255, 255, 255, 0.45);
7203
+ }
package/dist/charts.js CHANGED
@@ -39,10 +39,10 @@ import {
39
39
  setPlotlySource,
40
40
  uid,
41
41
  updateChart
42
- } from "./chunk-4RGQSRMC.js";
42
+ } from "./chunk-SWB5ARKN.js";
43
43
  import {
44
44
  createRafResizeObserver
45
- } from "./chunk-P4AALM3A.js";
45
+ } from "./chunk-BIAOGX6K.js";
46
46
  import {
47
47
  ManagedWindow
48
48
  } from "./chunk-LH5TSOZW.js";
@@ -302,6 +302,8 @@ var DataTable = class {
302
302
  */
303
303
  render() {
304
304
  const activeFilterColIdx = this._getActiveFilterColIdx();
305
+ const doc = this.container.ownerDocument;
306
+ const hadTableFocus = !!this._tableEl && doc?.activeElement === this._tableEl;
305
307
  this._cleanup();
306
308
  this.container.innerHTML = "";
307
309
  const { rows, pagination, emptyMessage } = this.config;
@@ -412,6 +414,11 @@ var DataTable = class {
412
414
  }
413
415
  if (activeFilterColIdx !== null) {
414
416
  this._restoreFilterFocus(activeFilterColIdx);
417
+ } else if (hadTableFocus && this._tableEl) {
418
+ try {
419
+ this._tableEl.focus({ preventScroll: true });
420
+ } catch (_) {
421
+ }
415
422
  }
416
423
  }
417
424
  /**
@@ -1717,28 +1724,48 @@ var DataTable = class {
1717
1724
  th.appendChild(grip);
1718
1725
  });
1719
1726
  }
1727
+ /**
1728
+ * CSS px per screen px. Content inside a zoomed tile reports rects and
1729
+ * pointer coordinates in screen pixels, while `style.width` is CSS pixels;
1730
+ * mixing them widened every column by the zoom factor on a mere click.
1731
+ */
1732
+ _zoomFactor() {
1733
+ const el = this._tableWrapEl || this._tableEl;
1734
+ const css = el?.offsetWidth || 0;
1735
+ const screen = el?.getBoundingClientRect?.().width || 0;
1736
+ return css > 0 && screen > 0 ? screen / css : 1;
1737
+ }
1720
1738
  _beginColResize(ev, domIdx) {
1739
+ if (ev.button != null && ev.button !== 0) return;
1721
1740
  ev.preventDefault();
1722
1741
  ev.stopPropagation();
1723
1742
  const headerTable = this._headerTableEl;
1724
1743
  const bodyTable = this._tableEl;
1725
1744
  const headRow = headerTable && headerTable.querySelector("thead > tr");
1726
1745
  if (!headRow) return;
1727
- const startWidths = [...headRow.children].map(
1728
- (c) => c.getBoundingClientRect().width
1729
- );
1730
- headerTable.style.tableLayout = "fixed";
1731
- if (bodyTable) bodyTable.style.tableLayout = "fixed";
1732
- startWidths.forEach((w, i) => this._pinColumnWidth(i, w));
1733
- this._applyTableWidth();
1734
1746
  const startX = ev.clientX;
1747
+ const THRESHOLD = 3;
1735
1748
  const MIN = 40;
1736
- document.body.classList.add("twm-dt-col-resizing");
1749
+ let startWidths = null;
1750
+ const begin = () => {
1751
+ const z = this._zoomFactor();
1752
+ startWidths = [...headRow.children].map((c) => {
1753
+ const set = parseFloat(c.style.width);
1754
+ return Number.isFinite(set) ? set : c.getBoundingClientRect().width / z;
1755
+ });
1756
+ headerTable.style.tableLayout = "fixed";
1757
+ if (bodyTable) bodyTable.style.tableLayout = "fixed";
1758
+ startWidths.forEach((w, i) => this._pinColumnWidth(i, w));
1759
+ this._applyTableWidth();
1760
+ document.body.classList.add("twm-dt-col-resizing");
1761
+ };
1737
1762
  const onMove = (mv) => {
1738
- const w = Math.max(
1739
- MIN,
1740
- Math.round(startWidths[domIdx] + (mv.clientX - startX))
1741
- );
1763
+ const dx = mv.clientX - startX;
1764
+ if (!startWidths) {
1765
+ if (Math.abs(dx) < THRESHOLD) return;
1766
+ begin();
1767
+ }
1768
+ const w = Math.max(MIN, Math.round(startWidths[domIdx] + dx / this._zoomFactor()));
1742
1769
  this._pinColumnWidth(domIdx, w);
1743
1770
  this._applyTableWidth(domIdx);
1744
1771
  this._syncHeaderScroll();
@@ -1746,6 +1773,7 @@ var DataTable = class {
1746
1773
  const onUp = () => {
1747
1774
  document.removeEventListener("mousemove", onMove);
1748
1775
  document.removeEventListener("mouseup", onUp);
1776
+ if (!startWidths) return;
1749
1777
  document.body.classList.remove("twm-dt-col-resizing");
1750
1778
  this._updateCellTooltips();
1751
1779
  this._savePersisted();
@@ -2065,4 +2093,4 @@ export {
2065
2093
  createRafResizeObserver,
2066
2094
  DataTable
2067
2095
  };
2068
- //# sourceMappingURL=chunk-P4AALM3A.js.map
2096
+ //# sourceMappingURL=chunk-BIAOGX6K.js.map