@yuneta/gobj-ui 7.23.44 → 7.23.45

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.
@@ -54352,6 +54352,7 @@ function create_popover_base(left, top, className, borderColor, minWidth) {
54352
54352
  popover.style.cssText = "position:absolute;left:" + left + "px;top:" + top + "px;background:var(--bulma-scheme-main, #fff);color:var(--bulma-text-strong, #1A1A1A);border:1px solid " + borderColor + ";border-radius:6px;padding:12px;z-index:100;pointer-events:all;box-shadow:0 4px 12px rgba(0,0,0,0.15);min-width:" + minWidth + "px;font-size:13px;";
54353
54353
  popover.addEventListener("click", (e) => e.stopPropagation());
54354
54354
  popover.addEventListener("pointerdown", (e) => e.stopPropagation());
54355
+ popover.addEventListener("wheel", (e) => e.stopPropagation());
54355
54356
  return popover;
54356
54357
  }
54357
54358
  /************************************************************
@@ -55801,6 +55802,7 @@ function show_node_detail_popover(gobj, node_id) {
55801
55802
  popover.style.maxWidth = "320px";
55802
55803
  popover.style.maxHeight = "60%";
55803
55804
  popover.style.overflow = "auto";
55805
+ popover.style.padding = "0 12px 12px";
55804
55806
  popover.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
55805
55807
  let rows = "";
55806
55808
  for (let key of Object.keys(record)) {
@@ -55811,9 +55813,9 @@ function show_node_detail_popover(gobj, node_id) {
55811
55813
  else if (typeof v === "object") vs = JSON.stringify(v);
55812
55814
  else vs = String(v);
55813
55815
  if (vs.length > 240) vs = vs.slice(0, 240) + "…";
55814
- rows += `<div style="display:flex;gap:10px;padding:5px 0;border-top:1px solid ${rowbd};"><div style="flex:0 0 38%;color:${sub};font-size:12px;word-break:break-word;">${(0, _yuneta_gobj_js.escapeHtml)(key)}</div><div style="flex:1 1 auto;font-size:12px;word-break:break-word;">${(0, _yuneta_gobj_js.escapeHtml)(vs)}</div></div>`;
55816
+ rows += `<div class="g6-detail-row" style="border-top:1px solid ${rowbd};"><div class="g6-detail-key" style="color:${sub};">${(0, _yuneta_gobj_js.escapeHtml)(key)}</div><div class="g6-detail-val">${(0, _yuneta_gobj_js.escapeHtml)(vs)}</div></div>`;
55815
55817
  }
55816
- popover.innerHTML = `<div style="display:flex;align-items:flex-start;gap:8px;margin-bottom:6px;"><div style="flex:1 1 auto;min-width:0;"><div style="font-size:14px;font-weight:600;word-break:break-word;">${(0, _yuneta_gobj_js.escapeHtml)(id)}</div><div style="font-size:11px;color:${sub};margin-top:2px;">${(0, _yuneta_gobj_js.escapeHtml)(topic)}</div></div><div class="g6-detail-close" style="flex:0 0 auto;cursor:pointer;font-size:16px;line-height:1;color:${sub};padding:0 2px;">×</div></div>` + (rows || `<div style="font-size:12px;color:${sub};">${(0, _yuneta_gobj_js.escapeHtml)((0, i18next.t)("no fields"))}</div>`);
55818
+ popover.innerHTML = `<div class="g6-detail-head" style="background:${bg};"><div style="flex:1 1 auto;min-width:0;"><div class="g6-detail-id">${(0, _yuneta_gobj_js.escapeHtml)(id)}</div><div class="g6-detail-topic" style="color:${sub};">${(0, _yuneta_gobj_js.escapeHtml)(topic)}</div></div><div class="g6-detail-close" role="button" tabindex="0" aria-label="${(0, _yuneta_gobj_js.escapeHtml)((0, i18next.t)("close"))}" title="${(0, _yuneta_gobj_js.escapeHtml)((0, i18next.t)("close"))}" style="color:${sub};">×</div></div>` + (rows || `<div class="g6-detail-empty" style="color:${sub};">${(0, _yuneta_gobj_js.escapeHtml)((0, i18next.t)("no fields"))}</div>`);
55817
55819
  let close_el = popover.querySelector(".g6-detail-close");
55818
55820
  if (close_el) close_el.addEventListener("click", (e) => {
55819
55821
  e.stopPropagation();
@@ -54347,6 +54347,7 @@ function create_popover_base(left, top, className, borderColor, minWidth) {
54347
54347
  popover.style.cssText = "position:absolute;left:" + left + "px;top:" + top + "px;background:var(--bulma-scheme-main, #fff);color:var(--bulma-text-strong, #1A1A1A);border:1px solid " + borderColor + ";border-radius:6px;padding:12px;z-index:100;pointer-events:all;box-shadow:0 4px 12px rgba(0,0,0,0.15);min-width:" + minWidth + "px;font-size:13px;";
54348
54348
  popover.addEventListener("click", (e) => e.stopPropagation());
54349
54349
  popover.addEventListener("pointerdown", (e) => e.stopPropagation());
54350
+ popover.addEventListener("wheel", (e) => e.stopPropagation());
54350
54351
  return popover;
54351
54352
  }
54352
54353
  /************************************************************
@@ -55796,6 +55797,7 @@ function show_node_detail_popover(gobj, node_id) {
55796
55797
  popover.style.maxWidth = "320px";
55797
55798
  popover.style.maxHeight = "60%";
55798
55799
  popover.style.overflow = "auto";
55800
+ popover.style.padding = "0 12px 12px";
55799
55801
  popover.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
55800
55802
  let rows = "";
55801
55803
  for (let key of Object.keys(record)) {
@@ -55806,9 +55808,9 @@ function show_node_detail_popover(gobj, node_id) {
55806
55808
  else if (typeof v === "object") vs = JSON.stringify(v);
55807
55809
  else vs = String(v);
55808
55810
  if (vs.length > 240) vs = vs.slice(0, 240) + "…";
55809
- rows += `<div style="display:flex;gap:10px;padding:5px 0;border-top:1px solid ${rowbd};"><div style="flex:0 0 38%;color:${sub};font-size:12px;word-break:break-word;">${escapeHtml(key)}</div><div style="flex:1 1 auto;font-size:12px;word-break:break-word;">${escapeHtml(vs)}</div></div>`;
55811
+ rows += `<div class="g6-detail-row" style="border-top:1px solid ${rowbd};"><div class="g6-detail-key" style="color:${sub};">${escapeHtml(key)}</div><div class="g6-detail-val">${escapeHtml(vs)}</div></div>`;
55810
55812
  }
55811
- popover.innerHTML = `<div style="display:flex;align-items:flex-start;gap:8px;margin-bottom:6px;"><div style="flex:1 1 auto;min-width:0;"><div style="font-size:14px;font-weight:600;word-break:break-word;">${escapeHtml(id)}</div><div style="font-size:11px;color:${sub};margin-top:2px;">${escapeHtml(topic)}</div></div><div class="g6-detail-close" style="flex:0 0 auto;cursor:pointer;font-size:16px;line-height:1;color:${sub};padding:0 2px;">×</div></div>` + (rows || `<div style="font-size:12px;color:${sub};">${escapeHtml(t("no fields"))}</div>`);
55813
+ popover.innerHTML = `<div class="g6-detail-head" style="background:${bg};"><div style="flex:1 1 auto;min-width:0;"><div class="g6-detail-id">${escapeHtml(id)}</div><div class="g6-detail-topic" style="color:${sub};">${escapeHtml(topic)}</div></div><div class="g6-detail-close" role="button" tabindex="0" aria-label="${escapeHtml(t("close"))}" title="${escapeHtml(t("close"))}" style="color:${sub};">×</div></div>` + (rows || `<div class="g6-detail-empty" style="color:${sub};">${escapeHtml(t("no fields"))}</div>`);
55812
55814
  let close_el = popover.querySelector(".g6-detail-close");
55813
55815
  if (close_el) close_el.addEventListener("click", (e) => {
55814
55816
  e.stopPropagation();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.44",
3
+ "version": "7.23.45",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -29,7 +29,7 @@
29
29
  "devDependencies": {
30
30
  "@rollup/plugin-terser": "^1.0.0",
31
31
  "@vitest/coverage-v8": "^4.1.10",
32
- "@yuneta/gobj-js": "^7.13.2",
32
+ "@yuneta/gobj-js": "^7.16.1",
33
33
  "vite": "^8.2.1",
34
34
  "vitest": "^4.1.10"
35
35
  },
@@ -3348,6 +3348,25 @@ function create_popover_base(left, top, className, borderColor, minWidth)
3348
3348
  'min-width:' + minWidth + 'px;font-size:13px;';
3349
3349
  popover.addEventListener('click', (e) => e.stopPropagation());
3350
3350
  popover.addEventListener('pointerdown', (e) => e.stopPropagation());
3351
+ /*
3352
+ * AND THE WHEEL, or a popover that overflows cannot be scrolled with
3353
+ * the wheel at all -- the scrollbar has to be dragged.
3354
+ *
3355
+ * G6's zoom behavior binds a wheel listener on the CONTAINER and
3356
+ * calls preventDefault() on every notch, whatever the target is;
3357
+ * then it declines to zoom because the target is not the canvas. So
3358
+ * the gesture is cancelled and nobody uses it: the graph does not
3359
+ * zoom AND the box does not scroll. Measured on a live node: with
3360
+ * the popover overflowing (scrollHeight 674 over 357 visible),
3361
+ * scrollTop stayed at 0 and the zoom readout stayed at 50%.
3362
+ *
3363
+ * Stopping it here -- in the bubble phase, where the click and the
3364
+ * pointerdown above are already stopped -- is enough: G6 sees
3365
+ * nothing and the browser scrolls the box normally. Not
3366
+ * preventDefault: cancelling it ourselves would be the same bug
3367
+ * from our side.
3368
+ */
3369
+ popover.addEventListener('wheel', (e) => e.stopPropagation());
3351
3370
  return popover;
3352
3371
  }
3353
3372
 
@@ -5492,6 +5511,9 @@ function show_node_detail_popover(gobj, node_id)
5492
5511
  popover.style.maxWidth = '320px';
5493
5512
  popover.style.maxHeight = '60%';
5494
5513
  popover.style.overflow = 'auto';
5514
+ /* The sticky head spans the full width, so the side padding moves
5515
+ * to the rows; `create_popover_base` put 12px on the box itself. */
5516
+ popover.style.padding = '0 12px 12px';
5495
5517
  popover.style.fontFamily =
5496
5518
  "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, " +
5497
5519
  "Helvetica, Arial, sans-serif";
@@ -5514,29 +5536,33 @@ function show_node_detail_popover(gobj, node_id)
5514
5536
  vs = vs.slice(0, 240) + '…';
5515
5537
  }
5516
5538
  rows +=
5517
- `<div style="display:flex;gap:10px;padding:5px 0;` +
5518
- `border-top:1px solid ${rowbd};">` +
5519
- `<div style="flex:0 0 38%;color:${sub};font-size:12px;` +
5520
- `word-break:break-word;">${escapeHtml(key)}</div>` +
5521
- `<div style="flex:1 1 auto;font-size:12px;` +
5522
- `word-break:break-word;">${escapeHtml(vs)}</div>` +
5539
+ `<div class="g6-detail-row" style="border-top:1px solid ${rowbd};">` +
5540
+ `<div class="g6-detail-key" style="color:${sub};">` +
5541
+ `${escapeHtml(key)}</div>` +
5542
+ `<div class="g6-detail-val">${escapeHtml(vs)}</div>` +
5523
5543
  `</div>`;
5524
5544
  }
5525
5545
 
5546
+ /*
5547
+ * The head is STICKY: the box scrolls, and with the head scrolling
5548
+ * away the ✕ left the screen -- on a phone, where the box is most
5549
+ * of the screen, that is a popover you cannot close without
5550
+ * scrolling back up for the button. Its background is the
5551
+ * popover's own, or the rows would show through it.
5552
+ */
5526
5553
  popover.innerHTML =
5527
- `<div style="display:flex;align-items:flex-start;gap:8px;` +
5528
- `margin-bottom:6px;">` +
5554
+ `<div class="g6-detail-head" style="background:${bg};">` +
5529
5555
  `<div style="flex:1 1 auto;min-width:0;">` +
5530
- `<div style="font-size:14px;font-weight:600;` +
5531
- `word-break:break-word;">${escapeHtml(id)}</div>` +
5532
- `<div style="font-size:11px;color:${sub};` +
5533
- `margin-top:2px;">${escapeHtml(topic)}</div>` +
5556
+ `<div class="g6-detail-id">${escapeHtml(id)}</div>` +
5557
+ `<div class="g6-detail-topic" style="color:${sub};">` +
5558
+ `${escapeHtml(topic)}</div>` +
5534
5559
  `</div>` +
5535
- `<div class="g6-detail-close" style="flex:0 0 auto;` +
5536
- `cursor:pointer;font-size:16px;line-height:1;` +
5537
- `color:${sub};padding:0 2px;">×</div>` +
5560
+ `<div class="g6-detail-close" role="button" tabindex="0"` +
5561
+ ` aria-label="${escapeHtml(t('close'))}"` +
5562
+ ` title="${escapeHtml(t('close'))}"` +
5563
+ ` style="color:${sub};">×</div>` +
5538
5564
  `</div>` +
5539
- (rows || `<div style="font-size:12px;color:${sub};">` +
5565
+ (rows || `<div class="g6-detail-empty" style="color:${sub};">` +
5540
5566
  `${escapeHtml(t('no fields'))}</div>`);
5541
5567
 
5542
5568
  let close_el = popover.querySelector('.g6-detail-close');
package/src/lib_graph.css CHANGED
@@ -111,6 +111,116 @@
111
111
  background-color: var(--bulma-background, #fff);
112
112
  }
113
113
 
114
+ /*
115
+ * THE NODE DETAIL POPOVER.
116
+ *
117
+ * Sizes live here and not in the inline styles that build it, for one
118
+ * reason: a media query cannot reach an inline style, and this box is
119
+ * read on a phone as much as on a desk.
120
+ *
121
+ * 12px was the size of the rows and 11px of the topic. That is caption
122
+ * size, and this popover exists ONLY to be read -- it is the record of
123
+ * a node, field by field. Same reasoning as the context menu below:
124
+ * 12px is a caption, not content.
125
+ */
126
+ .graph-container .g6-detail-head {
127
+ display: flex;
128
+ align-items: flex-start;
129
+ gap: 8px;
130
+ /* Sticky, so the ✕ never scrolls off a box that is most of the
131
+ * screen on a phone. The 12px of side padding the popover used to
132
+ * carry moved to the rows, so the head reaches its edges. */
133
+ position: sticky;
134
+ top: 0;
135
+ z-index: 1;
136
+ padding: 12px 0 6px;
137
+ }
138
+
139
+ .graph-container .g6-detail-id {
140
+ font-size: 15px;
141
+ font-weight: 600;
142
+ word-break: break-word;
143
+ }
144
+
145
+ .graph-container .g6-detail-topic {
146
+ font-size: 12px;
147
+ margin-top: 2px;
148
+ word-break: break-word;
149
+ }
150
+
151
+ .graph-container .g6-detail-row {
152
+ display: flex;
153
+ gap: 10px;
154
+ padding: 6px 0;
155
+ }
156
+
157
+ .graph-container .g6-detail-key,
158
+ .graph-container .g6-detail-val,
159
+ .graph-container .g6-detail-empty {
160
+ font-size: 13px;
161
+ word-break: break-word;
162
+ }
163
+
164
+ .graph-container .g6-detail-key {
165
+ flex: 0 0 38%;
166
+ }
167
+
168
+ .graph-container .g6-detail-val {
169
+ flex: 1 1 auto;
170
+ }
171
+
172
+ /*
173
+ * The close button was a 13x16 box: a glyph with 2px of side padding
174
+ * and nothing else. That is a mouse target on a good day and not a
175
+ * finger target on any. It is a real box now, and a square one, so the
176
+ * ✕ has somewhere to be.
177
+ */
178
+ .graph-container .g6-detail-close {
179
+ flex: 0 0 auto;
180
+ cursor: pointer;
181
+ font-size: 18px;
182
+ line-height: 1;
183
+ display: flex;
184
+ align-items: center;
185
+ justify-content: center;
186
+ width: 28px;
187
+ height: 28px;
188
+ margin: -4px -4px 0 0;
189
+ border-radius: 4px;
190
+ }
191
+
192
+ .graph-container .g6-detail-close:hover {
193
+ background: var(--bulma-background, rgba(128, 128, 128, 0.15));
194
+ }
195
+
196
+ /*
197
+ * A finger, and the rule the context menu below already follows: the
198
+ * target grows to something a thumb hits, and the text to something
199
+ * read at arm's length.
200
+ */
201
+ @media (pointer: coarse) {
202
+ .graph-container .g6-detail-close {
203
+ width: 44px;
204
+ height: 44px;
205
+ font-size: 22px;
206
+ margin: -8px -8px 0 0;
207
+ }
208
+ .graph-container .g6-detail-id {
209
+ font-size: 16px;
210
+ }
211
+ .graph-container .g6-detail-topic {
212
+ font-size: 13px;
213
+ }
214
+ .graph-container .g6-detail-key,
215
+ .graph-container .g6-detail-val,
216
+ .graph-container .g6-detail-empty {
217
+ font-size: 14px;
218
+ }
219
+ .graph-container .g6-detail-row {
220
+ padding: 8px 0;
221
+ }
222
+ }
223
+
114
224
  /*
115
225
  * G6 toolbar: larger icons (via className option)
116
226
  */