@yuneta/gobj-ui 7.23.14 → 7.23.16

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
@@ -857,7 +857,10 @@ structural rather than cosmetic — and none of them is visible in the CSS:
857
857
  - **One finger has to serve three commands, so the press is arbitrated — at
858
858
  the RELEASE** (`press_arbiter.js`, pure and tested): moved → drag; still and
859
859
  let go quickly → the element's own action; still and held past 500ms → the
860
- context menu. Firing the menu on a TIMER instead cannot arbitrate anything,
860
+ context menu — with a 15ms haptic tick at the 500ms mark, which is a NOTICE
861
+ and not the decision (a finger that buzzes and then carries the node away
862
+ still gets its drag). Firing the menu on a TIMER instead cannot arbitrate
863
+ anything,
861
864
  because at the moment it fires the gesture is not over: it opened while
862
865
  `drag-element` was already carrying the node, so one press meant both things
863
866
  and the menu sat over a card running away underneath it. Two more things the
@@ -9775,7 +9775,15 @@ function install_long_press_contextmenu(graph, options) {
9775
9775
  let state = touch_state_of(graph);
9776
9776
  let pending = null;
9777
9777
  let disarm = () => {
9778
- pending = null;
9778
+ if (pending) {
9779
+ clearTimeout(pending.tick);
9780
+ pending = null;
9781
+ }
9782
+ };
9783
+ let announce = () => {
9784
+ if (!pending) return;
9785
+ if (state.multi) return;
9786
+ navigator.vibrate?.(15);
9779
9787
  };
9780
9788
  let fire = (event) => {
9781
9789
  state.long_press_click = true;
@@ -9805,7 +9813,8 @@ function install_long_press_contextmenu(graph, options) {
9805
9813
  x,
9806
9814
  y,
9807
9815
  t0: Date.now(),
9808
- event: Object.assign({}, event)
9816
+ event: Object.assign({}, event),
9817
+ tick: setTimeout(announce, 500)
9809
9818
  };
9810
9819
  };
9811
9820
  let on_move = (event) => {
@@ -9821,6 +9830,7 @@ function install_long_press_contextmenu(graph, options) {
9821
9830
  };
9822
9831
  let on_up = (event) => {
9823
9832
  let press = pending;
9833
+ if (press) clearTimeout(press.tick);
9824
9834
  pending = null;
9825
9835
  if (!press) return;
9826
9836
  if (state.multi) return;
@@ -9770,7 +9770,15 @@ function install_long_press_contextmenu(graph, options) {
9770
9770
  let state = touch_state_of(graph);
9771
9771
  let pending = null;
9772
9772
  let disarm = () => {
9773
- pending = null;
9773
+ if (pending) {
9774
+ clearTimeout(pending.tick);
9775
+ pending = null;
9776
+ }
9777
+ };
9778
+ let announce = () => {
9779
+ if (!pending) return;
9780
+ if (state.multi) return;
9781
+ navigator.vibrate?.(15);
9774
9782
  };
9775
9783
  let fire = (event) => {
9776
9784
  state.long_press_click = true;
@@ -9800,7 +9808,8 @@ function install_long_press_contextmenu(graph, options) {
9800
9808
  x,
9801
9809
  y,
9802
9810
  t0: Date.now(),
9803
- event: Object.assign({}, event)
9811
+ event: Object.assign({}, event),
9812
+ tick: setTimeout(announce, 500)
9804
9813
  };
9805
9814
  };
9806
9815
  let on_move = (event) => {
@@ -9816,6 +9825,7 @@ function install_long_press_contextmenu(graph, options) {
9816
9825
  };
9817
9826
  let on_up = (event) => {
9818
9827
  let press = pending;
9828
+ if (press) clearTimeout(press.tick);
9819
9829
  pending = null;
9820
9830
  if (!press) return;
9821
9831
  if (state.multi) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.14",
3
+ "version": "7.23.16",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -65,7 +65,7 @@ import {
65
65
  register,
66
66
  } from '@antv/g6';
67
67
 
68
- import {press_moved, classify_press} from "./press_arbiter.js";
68
+ import {press_moved, classify_press, LONG_PRESS_MS} from "./press_arbiter.js";
69
69
 
70
70
 
71
71
  /***************************************************************
@@ -372,10 +372,36 @@ export function install_long_press_contextmenu(graph, options)
372
372
 
373
373
  let enable = options?.enable;
374
374
  let state = touch_state_of(graph);
375
- let pending = null; /* {x, y, t0, event} */
375
+ let pending = null; /* {x, y, t0, event, tick} */
376
376
 
377
377
  let disarm = () => {
378
- pending = null;
378
+ if(pending) {
379
+ clearTimeout(pending.tick);
380
+ pending = null;
381
+ }
382
+ };
383
+
384
+ /*
385
+ * The one thing deciding at the RELEASE costs: while the finger
386
+ * is down, nothing on the screen says the menu is now what
387
+ * letting go would give you. A tick of haptics says it.
388
+ *
389
+ * It is a NOTICE, not the decision -- the arbitration is still
390
+ * entirely in `on_up`. So a finger that buzzes and then carries
391
+ * the node away gets its drag, exactly as if it had never
392
+ * buzzed; the tick only reports what the press is worth at the
393
+ * moment it crosses the line. (Where there is no vibrator --
394
+ * iOS Safari, a desktop -- `vibrate` is simply absent and this
395
+ * is a no-op.)
396
+ */
397
+ let announce = () => {
398
+ if(!pending) {
399
+ return;
400
+ }
401
+ if(state.multi) {
402
+ return;
403
+ }
404
+ navigator.vibrate?.(15);
379
405
  };
380
406
 
381
407
  let fire = (event) => {
@@ -437,6 +463,7 @@ export function install_long_press_contextmenu(graph, options)
437
463
  y: y,
438
464
  t0: Date.now(),
439
465
  event: Object.assign({}, event),
466
+ tick: setTimeout(announce, LONG_PRESS_MS),
440
467
  };
441
468
  };
442
469
 
@@ -460,6 +487,9 @@ export function install_long_press_contextmenu(graph, options)
460
487
 
461
488
  let on_up = (event) => {
462
489
  let press = pending;
490
+ if(press) {
491
+ clearTimeout(press.tick);
492
+ }
463
493
  pending = null;
464
494
  if(!press) {
465
495
  return;
@@ -6,6 +6,15 @@
6
6
  width: 100%;
7
7
  height: auto;
8
8
  position: relative;
9
+ /* The toolbar is often a flex item sharing its row with a pinned
10
+ * control (a back link, a title). A flex item's `min-width:auto`
11
+ * resolves to the CONTENT minimum, and the sections inside are
12
+ * `flex-shrink:0; white-space:nowrap` — so the toolbar refuses to
13
+ * shrink, the row overflows, and the scroll container never sees an
14
+ * overflow of its OWN: both arrows stay hidden while the items are
15
+ * clipped by an ancestor. Alone on its row nothing shrinks and the
16
+ * bug hides, which is why it only shows up once integrated. */
17
+ min-width: 0;
9
18
  }
10
19
 
11
20
  .yui-horizontal-toolbar-container {