@yuneta/gobj-ui 7.23.89 → 7.23.91

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.
@@ -54572,8 +54572,16 @@ ensure_pinch_zoom_patch();
54572
54572
  * Constants
54573
54573
  ***************************************************************/
54574
54574
  var GCLASS_NAME$4 = "C_G6_NODES_TREE";
54575
- var HIGHLIGHT_COLOR = "#f0a020";
54576
- var HIGHLIGHT_HALO = "rgba(240,160,32,0.35)";
54575
+ var HIGHLIGHT_COLOR_DARK = "#f0a020";
54576
+ var HIGHLIGHT_COLOR_LIGHT = "#b45309";
54577
+ var HIGHLIGHT_HALO_DARK = "rgba(240,160,32,0.35)";
54578
+ var HIGHLIGHT_HALO_LIGHT = "rgba(180,83,9,0.35)";
54579
+ function highlight_color(theme) {
54580
+ return theme === "dark" ? HIGHLIGHT_COLOR_DARK : HIGHLIGHT_COLOR_LIGHT;
54581
+ }
54582
+ function highlight_halo(theme) {
54583
+ return theme === "dark" ? HIGHLIGHT_HALO_DARK : HIGHLIGHT_HALO_LIGHT;
54584
+ }
54577
54585
  var SELECT_RING = "rgba(59,130,246,0.95)";
54578
54586
  var PORT_R_ENTITY = 14;
54579
54587
  var PORT_R_CHILD = 8;
@@ -55491,6 +55499,53 @@ function calculate_hooks_fkeys_counter(desc) {
55491
55499
  /************************************************************
55492
55500
  * Build ports for a topic desc
55493
55501
  ************************************************************/
55502
+ /************************************************************
55503
+ * Mix two colours the way `color-mix(in srgb, a p%, b)` does,
55504
+ * in JS.
55505
+ *
55506
+ * The cards are html and can say `color-mix()`; a PORT is drawn
55507
+ * on the canvas by `@antv/g`, which parses a colour string and
55508
+ * knows nothing about CSS functions -- so the same arithmetic
55509
+ * has to happen here.
55510
+ ************************************************************/
55511
+ function mix_colors(a, p, b) {
55512
+ let rgb = (c) => {
55513
+ if (c.charAt(0) === "#") {
55514
+ let h = c.slice(1);
55515
+ if (h.length === 3) h = h.split("").map((x) => x + x).join("");
55516
+ return [
55517
+ 0,
55518
+ 2,
55519
+ 4
55520
+ ].map((i) => parseInt(h.slice(i, i + 2), 16));
55521
+ }
55522
+ return (c.match(/[\d.]+/g) || []).map(Number).slice(0, 3);
55523
+ };
55524
+ let A = rgb(a);
55525
+ let B = rgb(b);
55526
+ return `rgb(${A.map((v, i) => Math.round(v * p + B[i] * (1 - p))).join(",")})`;
55527
+ }
55528
+ /************************************************************
55529
+ * The rim of a port.
55530
+ *
55531
+ * A port is a knob half on a CARD and half on the canvas, and
55532
+ * the card is a tint of a topic colour -- so a port of that
55533
+ * same topic used to sit on its own colour: 2.62:1 against the
55534
+ * card in dark, 1.54 in light, where a graphical object needs
55535
+ * 3:1 to be told from what is next to it. The FILL keeps saying
55536
+ * which topic links there; the rim is what separates it, and it
55537
+ * is the port's own colour pushed towards the surface -- 60% of
55538
+ * the hue is enough to clear 3:1 on both grounds in both
55539
+ * themes (4.49 / 3.64 against the card, 9.11 / 3.80 against the
55540
+ * canvas) and little enough to keep the hue.
55541
+ *
55542
+ * It used to be `getStrokeColor(color)` called with no theme,
55543
+ * which is its LIGHT branch always: a rim darkened by 20% of a
55544
+ * colour, on a card of the same colour.
55545
+ ************************************************************/
55546
+ function port_rim(color, theme) {
55547
+ return mix_colors(color, .6, theme === "dark" ? "#ffffff" : "#0f172a");
55548
+ }
55494
55549
  function build_ports(gobj, desc) {
55495
55550
  let priv = gobj.priv;
55496
55551
  let top_ports = [];
@@ -55509,7 +55564,7 @@ function build_ports(gobj, desc) {
55509
55564
  port = {
55510
55565
  key: col.id,
55511
55566
  fill: child_desc ? child_desc.color : desc.color,
55512
- stroke: getStrokeColor(desc.color)
55567
+ stroke: port_rim(child_desc ? child_desc.color : desc.color, priv.theme)
55513
55568
  };
55514
55569
  bottom_ports.push(port);
55515
55570
  }
@@ -55518,7 +55573,7 @@ function build_ports(gobj, desc) {
55518
55573
  port = {
55519
55574
  key: col.id,
55520
55575
  fill: desc.color,
55521
- stroke: getStrokeColor(desc.color)
55576
+ stroke: port_rim(desc.color, priv.theme)
55522
55577
  };
55523
55578
  top_ports.push(port);
55524
55579
  }
@@ -55879,7 +55934,8 @@ function node_figure_of(gobj, desc, geometry) {
55879
55934
  * flags {highlight, selected, anchored}
55880
55935
  ************************************************************/
55881
55936
  function figure_shape_of(gobj, desc, record, geometry, flags) {
55882
- let dark = gobj.priv.theme === "dark";
55937
+ let priv = gobj.priv;
55938
+ let dark = priv.theme === "dark";
55883
55939
  let f = flags || {};
55884
55940
  let tier = desc.node_treedb_type;
55885
55941
  let side = SHAPE_SIZE[tier] || SHAPE_SIZE.hierarchical;
@@ -55893,7 +55949,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
55893
55949
  line_width = 3;
55894
55950
  }
55895
55951
  if (f.highlight) {
55896
- stroke = HIGHLIGHT_COLOR;
55952
+ stroke = highlight_color(priv.theme);
55897
55953
  line_width = 3;
55898
55954
  }
55899
55955
  let dash = [];
@@ -55910,7 +55966,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
55910
55966
  lineWidth: line_width,
55911
55967
  lineDash: dash,
55912
55968
  halo: !!f.highlight,
55913
- haloStroke: HIGHLIGHT_HALO,
55969
+ haloStroke: highlight_halo(priv.theme),
55914
55970
  haloLineWidth: 8,
55915
55971
  port: false,
55916
55972
  ports: [],
@@ -58920,7 +58976,7 @@ function auto_layout(gobj) {
58920
58976
  * Its shapes are drawn by hand. G6's minimap clones each element's key
58921
58977
  * shape into its own canvas, and every node here is an `html` node
58922
58978
  * whose key shape is a DOM element — the same reason the `active`
58923
- * state never painted (see HIGHLIGHT_COLOR). A block in the topic's
58979
+ * state never painted (see highlight_color()). A block in the topic's
58924
58980
  * colour is also what a minimap of cards SHOULD show: at that scale a
58925
58981
  * card is a rectangle anyway.
58926
58982
  ************************************************************/
@@ -59143,9 +59199,9 @@ function refresh_default_edges_theme(gobj, theme) {
59143
59199
  function anchor_outline(anchored) {
59144
59200
  return anchored ? "outline: 3px dashed #fa8c16; outline-offset: 2px;" : "";
59145
59201
  }
59146
- function ring_shadow(highlight, selected, base_shadow) {
59202
+ function ring_shadow(highlight, selected, base_shadow, theme) {
59147
59203
  let rings = [];
59148
- if (highlight) rings.push(`0 0 0 4px ${HIGHLIGHT_HALO}`);
59204
+ if (highlight) rings.push(`0 0 0 4px ${highlight_halo(theme)}`);
59149
59205
  if (selected) rings.push(`0 0 0 ${highlight ? "7px" : "3px"} ${SELECT_RING}`);
59150
59206
  if (base_shadow) rings.push(base_shadow);
59151
59207
  if (!rings.length) return "";
@@ -59160,10 +59216,10 @@ function ring_shadow(highlight, selected, base_shadow) {
59160
59216
  function build_chip_innerHTML(color, theme, icon, label, key, highlight, selected, anchored) {
59161
59217
  let title = key || label;
59162
59218
  let dark = theme === "dark";
59163
- let bg = dark ? `color-mix(in srgb, ${color} 30%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${dark ? "#1b2230" : "#ffffff"})`;
59219
+ let bg = dark ? `color-mix(in srgb, ${color} 25%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${dark ? "#1b2230" : "#ffffff"})`;
59164
59220
  let border = dark ? `color-mix(in srgb, ${color} 85%, #ffffff)` : color;
59165
59221
  let text_color = dark ? "#e8eaed" : "#0f172a";
59166
- if (highlight) border = HIGHLIGHT_COLOR;
59222
+ if (highlight) border = highlight_color(theme);
59167
59223
  let icon_html = "";
59168
59224
  if (icon) icon_html = `<img src="${(0, _yuneta_gobj_js.safeSrc)(icon)}" alt="" style="
59169
59225
  width: 16px; height: 16px; object-fit: contain;
@@ -59176,7 +59232,7 @@ function build_chip_innerHTML(color, theme, icon, label, key, highlight, selecte
59176
59232
  height: 100%;
59177
59233
  background: ${bg};
59178
59234
  border: ${highlight ? "3px" : "1px"} solid ${border};
59179
- ${ring_shadow(highlight, selected, "")}
59235
+ ${ring_shadow(highlight, selected, "", theme)}
59180
59236
  ${anchor_outline(anchored)}
59181
59237
  border-radius: 8px;
59182
59238
  color: ${text_color};
@@ -59213,16 +59269,16 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
59213
59269
  border = dark ? "#7c8694" : "#94a3b8";
59214
59270
  border_style = "dashed";
59215
59271
  } else {
59216
- bg = dark ? `color-mix(in srgb, ${color} 30%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${surface})`;
59272
+ bg = dark ? `color-mix(in srgb, ${color} 25%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${surface})`;
59217
59273
  border = dark ? `color-mix(in srgb, ${color} 85%, #ffffff)` : color;
59218
59274
  border_style = "solid";
59219
59275
  }
59220
59276
  if (highlight) {
59221
- border = HIGHLIGHT_COLOR;
59277
+ border = highlight_color(theme);
59222
59278
  border_style = "solid";
59223
59279
  }
59224
59280
  let title_color = dark ? "#e8eaed" : "#0f172a";
59225
- let sub_color = dark ? "#9aa4b2" : "#64748b";
59281
+ let sub_color = dark ? "#ccd3dd" : "#556173";
59226
59282
  let shadow = dark ? "0 1px 3px rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.30)" : "0 1px 3px rgba(15,23,42,0.12), 0 1px 2px rgba(15,23,42,0.06)";
59227
59283
  let icon_html = "";
59228
59284
  if (icon) icon_html = `
@@ -59251,7 +59307,7 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
59251
59307
  background: ${bg};
59252
59308
  border: ${highlight ? "3px" : "1.5px"} ${border_style} ${border};
59253
59309
  border-radius: 10px;
59254
- ${ring_shadow(highlight, selected, shadow)}
59310
+ ${ring_shadow(highlight, selected, shadow, theme)}
59255
59311
  ${anchor_outline(anchored)}
59256
59312
  color: ${title_color};
59257
59313
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
@@ -60054,7 +60110,7 @@ function pill_colors(color, theme) {
60054
60110
  let dark = theme === "dark";
60055
60111
  return {
60056
60112
  bg: dark ? `color-mix(in srgb, ${color} 45%, #1b2230)` : `color-mix(in srgb, ${color} 22%, #ffffff)`,
60057
- fg: dark ? `color-mix(in srgb, ${color} 35%, #ffffff)` : `color-mix(in srgb, ${color} 55%, #0f172a)`,
60113
+ fg: dark ? `color-mix(in srgb, ${color} 25%, #ffffff)` : `color-mix(in srgb, ${color} 45%, #0f172a)`,
60058
60114
  border: dark ? `color-mix(in srgb, ${color} 80%, #ffffff)` : color
60059
60115
  };
60060
60116
  }
@@ -60077,7 +60133,7 @@ function build_pill_html(pill, color, theme) {
60077
60133
  font-size: 10px; font-weight: 700; line-height: 1; white-space: nowrap;
60078
60134
  overflow: hidden; text-overflow: ellipsis;
60079
60135
  cursor: pointer; user-select: none;
60080
- "><span style="font-size: 9px;">${glyph}</span>${(0, _yuneta_gobj_js.escapeHtml)(pill.hook)}<span style="opacity: .75; font-weight: 600;">${count}</span></span>`;
60136
+ "><span style="font-size: 9px;">${glyph}</span>${(0, _yuneta_gobj_js.escapeHtml)(pill.hook)}<span style="font-weight: 600;">${count}</span></span>`;
60081
60137
  }
60082
60138
  /************************************************************
60083
60139
  * The pill row of one node, as html; "" when it has nothing to
@@ -60392,7 +60448,7 @@ async function reconcile_fold_apply(gobj, opts, visible) {
60392
60448
  sourcePort: p.hook,
60393
60449
  lineWidth: 1,
60394
60450
  lineDash: [4, 3],
60395
- stroke: dark ? "#8b94a3" : "#94a3b8",
60451
+ stroke: dark ? "#8b94a3" : "#6b7280",
60396
60452
  startArrow: false,
60397
60453
  endArrow: false
60398
60454
  },
@@ -60459,6 +60515,31 @@ function ac_language_changed$3(gobj, event, kw, src) {
60459
60515
  return 0;
60460
60516
  }
60461
60517
  /************************************************************
60518
+ * The rims of every port, on a theme change.
60519
+ *
60520
+ * A rim is half of the surface it sits on (see port_rim), so it
60521
+ * belongs to the theme -- and it lives in each node's
60522
+ * `style.ports`, which is the one place refresh_html_nodes_theme()
60523
+ * does not reach: it rebuilds the html INSIDE a card.
60524
+ ************************************************************/
60525
+ function refresh_port_rims(gobj, theme) {
60526
+ let graph = gobj.priv.graph;
60527
+ if (!graph) return;
60528
+ let updates = [];
60529
+ for (let nd of graph.getNodeData() || []) {
60530
+ if (!nd || !nd.style || !(0, _yuneta_gobj_js.is_array)(nd.style.ports) || !nd.style.ports.length) continue;
60531
+ updates.push({
60532
+ id: nd.id,
60533
+ style: { ports: nd.style.ports.map((p) => Object.assign({}, p, { stroke: port_rim(p.fill, theme) })) }
60534
+ });
60535
+ }
60536
+ if (updates.length) try {
60537
+ graph.updateNodeData(updates);
60538
+ } catch (e) {
60539
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot repaint the port rims: ${e}`);
60540
+ }
60541
+ }
60542
+ /************************************************************
60462
60543
  * Repaint the `+N` chips (theme or language changed).
60463
60544
  ************************************************************/
60464
60545
  function repaint_more_chips(gobj) {
@@ -60780,6 +60861,7 @@ function ac_theme$1(gobj, event, kw, src) {
60780
60861
  });
60781
60862
  refresh_html_nodes_theme(gobj, theme);
60782
60863
  refresh_default_edges_theme(gobj, theme);
60864
+ refresh_port_rims(gobj, theme);
60783
60865
  repaint_more_chips(gobj);
60784
60866
  graph_draw(gobj).then(() => {
60785
60867
  update_history_buttons(gobj);
@@ -54567,8 +54567,16 @@ ensure_pinch_zoom_patch();
54567
54567
  * Constants
54568
54568
  ***************************************************************/
54569
54569
  var GCLASS_NAME$4 = "C_G6_NODES_TREE";
54570
- var HIGHLIGHT_COLOR = "#f0a020";
54571
- var HIGHLIGHT_HALO = "rgba(240,160,32,0.35)";
54570
+ var HIGHLIGHT_COLOR_DARK = "#f0a020";
54571
+ var HIGHLIGHT_COLOR_LIGHT = "#b45309";
54572
+ var HIGHLIGHT_HALO_DARK = "rgba(240,160,32,0.35)";
54573
+ var HIGHLIGHT_HALO_LIGHT = "rgba(180,83,9,0.35)";
54574
+ function highlight_color(theme) {
54575
+ return theme === "dark" ? HIGHLIGHT_COLOR_DARK : HIGHLIGHT_COLOR_LIGHT;
54576
+ }
54577
+ function highlight_halo(theme) {
54578
+ return theme === "dark" ? HIGHLIGHT_HALO_DARK : HIGHLIGHT_HALO_LIGHT;
54579
+ }
54572
54580
  var SELECT_RING = "rgba(59,130,246,0.95)";
54573
54581
  var PORT_R_ENTITY = 14;
54574
54582
  var PORT_R_CHILD = 8;
@@ -55486,6 +55494,53 @@ function calculate_hooks_fkeys_counter(desc) {
55486
55494
  /************************************************************
55487
55495
  * Build ports for a topic desc
55488
55496
  ************************************************************/
55497
+ /************************************************************
55498
+ * Mix two colours the way `color-mix(in srgb, a p%, b)` does,
55499
+ * in JS.
55500
+ *
55501
+ * The cards are html and can say `color-mix()`; a PORT is drawn
55502
+ * on the canvas by `@antv/g`, which parses a colour string and
55503
+ * knows nothing about CSS functions -- so the same arithmetic
55504
+ * has to happen here.
55505
+ ************************************************************/
55506
+ function mix_colors(a, p, b) {
55507
+ let rgb = (c) => {
55508
+ if (c.charAt(0) === "#") {
55509
+ let h = c.slice(1);
55510
+ if (h.length === 3) h = h.split("").map((x) => x + x).join("");
55511
+ return [
55512
+ 0,
55513
+ 2,
55514
+ 4
55515
+ ].map((i) => parseInt(h.slice(i, i + 2), 16));
55516
+ }
55517
+ return (c.match(/[\d.]+/g) || []).map(Number).slice(0, 3);
55518
+ };
55519
+ let A = rgb(a);
55520
+ let B = rgb(b);
55521
+ return `rgb(${A.map((v, i) => Math.round(v * p + B[i] * (1 - p))).join(",")})`;
55522
+ }
55523
+ /************************************************************
55524
+ * The rim of a port.
55525
+ *
55526
+ * A port is a knob half on a CARD and half on the canvas, and
55527
+ * the card is a tint of a topic colour -- so a port of that
55528
+ * same topic used to sit on its own colour: 2.62:1 against the
55529
+ * card in dark, 1.54 in light, where a graphical object needs
55530
+ * 3:1 to be told from what is next to it. The FILL keeps saying
55531
+ * which topic links there; the rim is what separates it, and it
55532
+ * is the port's own colour pushed towards the surface -- 60% of
55533
+ * the hue is enough to clear 3:1 on both grounds in both
55534
+ * themes (4.49 / 3.64 against the card, 9.11 / 3.80 against the
55535
+ * canvas) and little enough to keep the hue.
55536
+ *
55537
+ * It used to be `getStrokeColor(color)` called with no theme,
55538
+ * which is its LIGHT branch always: a rim darkened by 20% of a
55539
+ * colour, on a card of the same colour.
55540
+ ************************************************************/
55541
+ function port_rim(color, theme) {
55542
+ return mix_colors(color, .6, theme === "dark" ? "#ffffff" : "#0f172a");
55543
+ }
55489
55544
  function build_ports(gobj, desc) {
55490
55545
  let priv = gobj.priv;
55491
55546
  let top_ports = [];
@@ -55504,7 +55559,7 @@ function build_ports(gobj, desc) {
55504
55559
  port = {
55505
55560
  key: col.id,
55506
55561
  fill: child_desc ? child_desc.color : desc.color,
55507
- stroke: getStrokeColor(desc.color)
55562
+ stroke: port_rim(child_desc ? child_desc.color : desc.color, priv.theme)
55508
55563
  };
55509
55564
  bottom_ports.push(port);
55510
55565
  }
@@ -55513,7 +55568,7 @@ function build_ports(gobj, desc) {
55513
55568
  port = {
55514
55569
  key: col.id,
55515
55570
  fill: desc.color,
55516
- stroke: getStrokeColor(desc.color)
55571
+ stroke: port_rim(desc.color, priv.theme)
55517
55572
  };
55518
55573
  top_ports.push(port);
55519
55574
  }
@@ -55874,7 +55929,8 @@ function node_figure_of(gobj, desc, geometry) {
55874
55929
  * flags {highlight, selected, anchored}
55875
55930
  ************************************************************/
55876
55931
  function figure_shape_of(gobj, desc, record, geometry, flags) {
55877
- let dark = gobj.priv.theme === "dark";
55932
+ let priv = gobj.priv;
55933
+ let dark = priv.theme === "dark";
55878
55934
  let f = flags || {};
55879
55935
  let tier = desc.node_treedb_type;
55880
55936
  let side = SHAPE_SIZE[tier] || SHAPE_SIZE.hierarchical;
@@ -55888,7 +55944,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
55888
55944
  line_width = 3;
55889
55945
  }
55890
55946
  if (f.highlight) {
55891
- stroke = HIGHLIGHT_COLOR;
55947
+ stroke = highlight_color(priv.theme);
55892
55948
  line_width = 3;
55893
55949
  }
55894
55950
  let dash = [];
@@ -55905,7 +55961,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
55905
55961
  lineWidth: line_width,
55906
55962
  lineDash: dash,
55907
55963
  halo: !!f.highlight,
55908
- haloStroke: HIGHLIGHT_HALO,
55964
+ haloStroke: highlight_halo(priv.theme),
55909
55965
  haloLineWidth: 8,
55910
55966
  port: false,
55911
55967
  ports: [],
@@ -58915,7 +58971,7 @@ function auto_layout(gobj) {
58915
58971
  * Its shapes are drawn by hand. G6's minimap clones each element's key
58916
58972
  * shape into its own canvas, and every node here is an `html` node
58917
58973
  * whose key shape is a DOM element — the same reason the `active`
58918
- * state never painted (see HIGHLIGHT_COLOR). A block in the topic's
58974
+ * state never painted (see highlight_color()). A block in the topic's
58919
58975
  * colour is also what a minimap of cards SHOULD show: at that scale a
58920
58976
  * card is a rectangle anyway.
58921
58977
  ************************************************************/
@@ -59138,9 +59194,9 @@ function refresh_default_edges_theme(gobj, theme) {
59138
59194
  function anchor_outline(anchored) {
59139
59195
  return anchored ? "outline: 3px dashed #fa8c16; outline-offset: 2px;" : "";
59140
59196
  }
59141
- function ring_shadow(highlight, selected, base_shadow) {
59197
+ function ring_shadow(highlight, selected, base_shadow, theme) {
59142
59198
  let rings = [];
59143
- if (highlight) rings.push(`0 0 0 4px ${HIGHLIGHT_HALO}`);
59199
+ if (highlight) rings.push(`0 0 0 4px ${highlight_halo(theme)}`);
59144
59200
  if (selected) rings.push(`0 0 0 ${highlight ? "7px" : "3px"} ${SELECT_RING}`);
59145
59201
  if (base_shadow) rings.push(base_shadow);
59146
59202
  if (!rings.length) return "";
@@ -59155,10 +59211,10 @@ function ring_shadow(highlight, selected, base_shadow) {
59155
59211
  function build_chip_innerHTML(color, theme, icon, label, key, highlight, selected, anchored) {
59156
59212
  let title = key || label;
59157
59213
  let dark = theme === "dark";
59158
- let bg = dark ? `color-mix(in srgb, ${color} 30%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${dark ? "#1b2230" : "#ffffff"})`;
59214
+ let bg = dark ? `color-mix(in srgb, ${color} 25%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${dark ? "#1b2230" : "#ffffff"})`;
59159
59215
  let border = dark ? `color-mix(in srgb, ${color} 85%, #ffffff)` : color;
59160
59216
  let text_color = dark ? "#e8eaed" : "#0f172a";
59161
- if (highlight) border = HIGHLIGHT_COLOR;
59217
+ if (highlight) border = highlight_color(theme);
59162
59218
  let icon_html = "";
59163
59219
  if (icon) icon_html = `<img src="${safeSrc(icon)}" alt="" style="
59164
59220
  width: 16px; height: 16px; object-fit: contain;
@@ -59171,7 +59227,7 @@ function build_chip_innerHTML(color, theme, icon, label, key, highlight, selecte
59171
59227
  height: 100%;
59172
59228
  background: ${bg};
59173
59229
  border: ${highlight ? "3px" : "1px"} solid ${border};
59174
- ${ring_shadow(highlight, selected, "")}
59230
+ ${ring_shadow(highlight, selected, "", theme)}
59175
59231
  ${anchor_outline(anchored)}
59176
59232
  border-radius: 8px;
59177
59233
  color: ${text_color};
@@ -59208,16 +59264,16 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
59208
59264
  border = dark ? "#7c8694" : "#94a3b8";
59209
59265
  border_style = "dashed";
59210
59266
  } else {
59211
- bg = dark ? `color-mix(in srgb, ${color} 30%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${surface})`;
59267
+ bg = dark ? `color-mix(in srgb, ${color} 25%, #2c3542)` : `color-mix(in srgb, ${color} 10%, ${surface})`;
59212
59268
  border = dark ? `color-mix(in srgb, ${color} 85%, #ffffff)` : color;
59213
59269
  border_style = "solid";
59214
59270
  }
59215
59271
  if (highlight) {
59216
- border = HIGHLIGHT_COLOR;
59272
+ border = highlight_color(theme);
59217
59273
  border_style = "solid";
59218
59274
  }
59219
59275
  let title_color = dark ? "#e8eaed" : "#0f172a";
59220
- let sub_color = dark ? "#9aa4b2" : "#64748b";
59276
+ let sub_color = dark ? "#ccd3dd" : "#556173";
59221
59277
  let shadow = dark ? "0 1px 3px rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.30)" : "0 1px 3px rgba(15,23,42,0.12), 0 1px 2px rgba(15,23,42,0.06)";
59222
59278
  let icon_html = "";
59223
59279
  if (icon) icon_html = `
@@ -59246,7 +59302,7 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
59246
59302
  background: ${bg};
59247
59303
  border: ${highlight ? "3px" : "1.5px"} ${border_style} ${border};
59248
59304
  border-radius: 10px;
59249
- ${ring_shadow(highlight, selected, shadow)}
59305
+ ${ring_shadow(highlight, selected, shadow, theme)}
59250
59306
  ${anchor_outline(anchored)}
59251
59307
  color: ${title_color};
59252
59308
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
@@ -60049,7 +60105,7 @@ function pill_colors(color, theme) {
60049
60105
  let dark = theme === "dark";
60050
60106
  return {
60051
60107
  bg: dark ? `color-mix(in srgb, ${color} 45%, #1b2230)` : `color-mix(in srgb, ${color} 22%, #ffffff)`,
60052
- fg: dark ? `color-mix(in srgb, ${color} 35%, #ffffff)` : `color-mix(in srgb, ${color} 55%, #0f172a)`,
60108
+ fg: dark ? `color-mix(in srgb, ${color} 25%, #ffffff)` : `color-mix(in srgb, ${color} 45%, #0f172a)`,
60053
60109
  border: dark ? `color-mix(in srgb, ${color} 80%, #ffffff)` : color
60054
60110
  };
60055
60111
  }
@@ -60072,7 +60128,7 @@ function build_pill_html(pill, color, theme) {
60072
60128
  font-size: 10px; font-weight: 700; line-height: 1; white-space: nowrap;
60073
60129
  overflow: hidden; text-overflow: ellipsis;
60074
60130
  cursor: pointer; user-select: none;
60075
- "><span style="font-size: 9px;">${glyph}</span>${escapeHtml(pill.hook)}<span style="opacity: .75; font-weight: 600;">${count}</span></span>`;
60131
+ "><span style="font-size: 9px;">${glyph}</span>${escapeHtml(pill.hook)}<span style="font-weight: 600;">${count}</span></span>`;
60076
60132
  }
60077
60133
  /************************************************************
60078
60134
  * The pill row of one node, as html; "" when it has nothing to
@@ -60387,7 +60443,7 @@ async function reconcile_fold_apply(gobj, opts, visible) {
60387
60443
  sourcePort: p.hook,
60388
60444
  lineWidth: 1,
60389
60445
  lineDash: [4, 3],
60390
- stroke: dark ? "#8b94a3" : "#94a3b8",
60446
+ stroke: dark ? "#8b94a3" : "#6b7280",
60391
60447
  startArrow: false,
60392
60448
  endArrow: false
60393
60449
  },
@@ -60454,6 +60510,31 @@ function ac_language_changed$3(gobj, event, kw, src) {
60454
60510
  return 0;
60455
60511
  }
60456
60512
  /************************************************************
60513
+ * The rims of every port, on a theme change.
60514
+ *
60515
+ * A rim is half of the surface it sits on (see port_rim), so it
60516
+ * belongs to the theme -- and it lives in each node's
60517
+ * `style.ports`, which is the one place refresh_html_nodes_theme()
60518
+ * does not reach: it rebuilds the html INSIDE a card.
60519
+ ************************************************************/
60520
+ function refresh_port_rims(gobj, theme) {
60521
+ let graph = gobj.priv.graph;
60522
+ if (!graph) return;
60523
+ let updates = [];
60524
+ for (let nd of graph.getNodeData() || []) {
60525
+ if (!nd || !nd.style || !is_array(nd.style.ports) || !nd.style.ports.length) continue;
60526
+ updates.push({
60527
+ id: nd.id,
60528
+ style: { ports: nd.style.ports.map((p) => Object.assign({}, p, { stroke: port_rim(p.fill, theme) })) }
60529
+ });
60530
+ }
60531
+ if (updates.length) try {
60532
+ graph.updateNodeData(updates);
60533
+ } catch (e) {
60534
+ log_error(`${gobj_short_name(gobj)}: cannot repaint the port rims: ${e}`);
60535
+ }
60536
+ }
60537
+ /************************************************************
60457
60538
  * Repaint the `+N` chips (theme or language changed).
60458
60539
  ************************************************************/
60459
60540
  function repaint_more_chips(gobj) {
@@ -60775,6 +60856,7 @@ function ac_theme$1(gobj, event, kw, src) {
60775
60856
  });
60776
60857
  refresh_html_nodes_theme(gobj, theme);
60777
60858
  refresh_default_edges_theme(gobj, theme);
60859
+ refresh_port_rims(gobj, theme);
60778
60860
  repaint_more_chips(gobj);
60779
60861
  graph_draw(gobj).then(() => {
60780
60862
  update_history_buttons(gobj);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.89",
3
+ "version": "7.23.91",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -240,8 +240,27 @@ const GCLASS_NAME = "C_G6_NODES_TREE";
240
240
  * is an `html` node, whose key shape is a DOM element — the state's
241
241
  * `stroke` / `halo` have nothing to paint on and the amber never
242
242
  * appeared, for the topic focus either. */
243
- const HIGHLIGHT_COLOR = "#f0a020";
244
- const HIGHLIGHT_HALO = "rgba(240,160,32,0.35)";
243
+ /* The mark of a focused topic and of a find: one amber for a
244
+ * near-black canvas (8.41:1) which on a WHITE one is 2.15 -- under
245
+ * the 3:1 a graphical mark needs, and this one is the whole answer
246
+ * to "which nodes matched". The light scheme takes the same hue
247
+ * burnt down (5.02:1); the halo follows it at the same alpha. Same
248
+ * rule as a brand colour used as ink: the colour that carries a
249
+ * mark is not one colour, it is one per scheme. */
250
+ const HIGHLIGHT_COLOR_DARK = "#f0a020";
251
+ const HIGHLIGHT_COLOR_LIGHT = "#b45309";
252
+ const HIGHLIGHT_HALO_DARK = "rgba(240,160,32,0.35)";
253
+ const HIGHLIGHT_HALO_LIGHT = "rgba(180,83,9,0.35)";
254
+
255
+ function highlight_color(theme)
256
+ {
257
+ return (theme === "dark")? HIGHLIGHT_COLOR_DARK : HIGHLIGHT_COLOR_LIGHT;
258
+ }
259
+
260
+ function highlight_halo(theme)
261
+ {
262
+ return (theme === "dark")? HIGHLIGHT_HALO_DARK : HIGHLIGHT_HALO_LIGHT;
263
+ }
245
264
 
246
265
  /*
247
266
  * The selection ring. Deliberately NOT the amber of the highlight:
@@ -1807,6 +1826,56 @@ function calculate_hooks_fkeys_counter(desc)
1807
1826
  /************************************************************
1808
1827
  * Build ports for a topic desc
1809
1828
  ************************************************************/
1829
+ /************************************************************
1830
+ * Mix two colours the way `color-mix(in srgb, a p%, b)` does,
1831
+ * in JS.
1832
+ *
1833
+ * The cards are html and can say `color-mix()`; a PORT is drawn
1834
+ * on the canvas by `@antv/g`, which parses a colour string and
1835
+ * knows nothing about CSS functions -- so the same arithmetic
1836
+ * has to happen here.
1837
+ ************************************************************/
1838
+ function mix_colors(a, p, b)
1839
+ {
1840
+ let rgb = (c) => {
1841
+ if(c.charAt(0) === "#") {
1842
+ let h = c.slice(1);
1843
+ if(h.length === 3) {
1844
+ h = h.split("").map((x) => x + x).join("");
1845
+ }
1846
+ return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16));
1847
+ }
1848
+ let n = (c.match(/[\d.]+/g) || []).map(Number);
1849
+ return n.slice(0, 3);
1850
+ };
1851
+ let A = rgb(a);
1852
+ let B = rgb(b);
1853
+ return `rgb(${A.map((v, i) => Math.round(v * p + B[i] * (1 - p))).join(",")})`;
1854
+ }
1855
+
1856
+ /************************************************************
1857
+ * The rim of a port.
1858
+ *
1859
+ * A port is a knob half on a CARD and half on the canvas, and
1860
+ * the card is a tint of a topic colour -- so a port of that
1861
+ * same topic used to sit on its own colour: 2.62:1 against the
1862
+ * card in dark, 1.54 in light, where a graphical object needs
1863
+ * 3:1 to be told from what is next to it. The FILL keeps saying
1864
+ * which topic links there; the rim is what separates it, and it
1865
+ * is the port's own colour pushed towards the surface -- 60% of
1866
+ * the hue is enough to clear 3:1 on both grounds in both
1867
+ * themes (4.49 / 3.64 against the card, 9.11 / 3.80 against the
1868
+ * canvas) and little enough to keep the hue.
1869
+ *
1870
+ * It used to be `getStrokeColor(color)` called with no theme,
1871
+ * which is its LIGHT branch always: a rim darkened by 20% of a
1872
+ * colour, on a card of the same colour.
1873
+ ************************************************************/
1874
+ function port_rim(color, theme)
1875
+ {
1876
+ return mix_colors(color, 0.6, (theme === "dark")? "#ffffff" : "#0f172a");
1877
+ }
1878
+
1810
1879
  function build_ports(gobj, desc)
1811
1880
  {
1812
1881
  let priv = gobj.priv;
@@ -1833,7 +1902,7 @@ function build_ports(gobj, desc)
1833
1902
  port = {
1834
1903
  key: col.id,
1835
1904
  fill: child_desc?child_desc.color:desc.color,
1836
- stroke: getStrokeColor(desc.color),
1905
+ stroke: port_rim(child_desc?child_desc.color:desc.color, priv.theme),
1837
1906
  };
1838
1907
  bottom_ports.push(port);
1839
1908
  }
@@ -1844,7 +1913,7 @@ function build_ports(gobj, desc)
1844
1913
  port = {
1845
1914
  key: col.id,
1846
1915
  fill: desc.color,
1847
- stroke: getStrokeColor(desc.color),
1916
+ stroke: port_rim(desc.color, priv.theme),
1848
1917
  };
1849
1918
  top_ports.push(port);
1850
1919
  break;
@@ -2374,7 +2443,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags)
2374
2443
  line_width = 3;
2375
2444
  }
2376
2445
  if(f.highlight) {
2377
- stroke = HIGHLIGHT_COLOR;
2446
+ stroke = highlight_color(priv.theme);
2378
2447
  line_width = 3;
2379
2448
  }
2380
2449
  /* Dashed says "structural", as the extended card does; the
@@ -2396,7 +2465,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags)
2396
2465
  lineWidth: line_width,
2397
2466
  lineDash: dash,
2398
2467
  halo: !!f.highlight,
2399
- haloStroke: HIGHLIGHT_HALO,
2468
+ haloStroke: highlight_halo(priv.theme),
2400
2469
  haloLineWidth: 8,
2401
2470
  port: false,
2402
2471
  ports: [],
@@ -6854,7 +6923,7 @@ function auto_layout(gobj)
6854
6923
  * Its shapes are drawn by hand. G6's minimap clones each element's key
6855
6924
  * shape into its own canvas, and every node here is an `html` node
6856
6925
  * whose key shape is a DOM element — the same reason the `active`
6857
- * state never painted (see HIGHLIGHT_COLOR). A block in the topic's
6926
+ * state never painted (see highlight_color()). A block in the topic's
6858
6927
  * colour is also what a minimap of cards SHOULD show: at that scale a
6859
6928
  * card is a rectangle anyway.
6860
6929
  ************************************************************/
@@ -7194,12 +7263,12 @@ function anchor_outline(anchored)
7194
7263
  return anchored? "outline: 3px dashed #fa8c16; outline-offset: 2px;" : "";
7195
7264
  }
7196
7265
 
7197
- function ring_shadow(highlight, selected, base_shadow)
7266
+ function ring_shadow(highlight, selected, base_shadow, theme)
7198
7267
  {
7199
7268
  let rings = [];
7200
7269
 
7201
7270
  if(highlight) {
7202
- rings.push(`0 0 0 4px ${HIGHLIGHT_HALO}`);
7271
+ rings.push(`0 0 0 4px ${highlight_halo(theme)}`);
7203
7272
  }
7204
7273
  if(selected) {
7205
7274
  rings.push(`0 0 0 ${highlight? "7px" : "3px"} ${SELECT_RING}`);
@@ -7225,15 +7294,18 @@ function build_chip_innerHTML(color, theme, icon, label, key, highlight, selecte
7225
7294
  let title = key || label;
7226
7295
  let dark = (theme === "dark");
7227
7296
  let surface = dark ? "#1b2230" : "#ffffff";
7297
+ /* The same 25% as the card (build_node_innerHTML): a leaf chip and
7298
+ * the card it hangs from are side by side, and two tints of one
7299
+ * colour read as two topics. */
7228
7300
  let bg = dark
7229
- ? `color-mix(in srgb, ${color} 30%, #2c3542)`
7301
+ ? `color-mix(in srgb, ${color} 25%, #2c3542)`
7230
7302
  : `color-mix(in srgb, ${color} 10%, ${surface})`;
7231
7303
  let border = dark
7232
7304
  ? `color-mix(in srgb, ${color} 85%, #ffffff)`
7233
7305
  : color;
7234
7306
  let text_color = dark ? "#e8eaed" : "#0f172a";
7235
7307
  if(highlight) {
7236
- border = HIGHLIGHT_COLOR;
7308
+ border = highlight_color(theme);
7237
7309
  }
7238
7310
 
7239
7311
  let icon_html = "";
@@ -7251,7 +7323,7 @@ function build_chip_innerHTML(color, theme, icon, label, key, highlight, selecte
7251
7323
  height: 100%;
7252
7324
  background: ${bg};
7253
7325
  border: ${highlight? "3px" : "1px"} solid ${border};
7254
- ${ring_shadow(highlight, selected, "")}
7326
+ ${ring_shadow(highlight, selected, "", theme)}
7255
7327
  ${anchor_outline(anchored)}
7256
7328
  border-radius: 8px;
7257
7329
  color: ${text_color};
@@ -7297,8 +7369,14 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
7297
7369
  // On dark, lift the card off the (near-black) canvas with a
7298
7370
  // clearly-lighter slate base + a vivid border, or the cards
7299
7371
  // become invisible.
7372
+ /* 25% and not 30% in dark: the tint is what says WHICH topic
7373
+ * a card belongs to, and it is also the ground everything on
7374
+ * the card is written on. At 30% the yellow of the palette
7375
+ * left the record's name at 5.17:1 and the topic under it at
7376
+ * 2.47 -- unreadable at 11px. Five points of tint buy the
7377
+ * name 5.80 and cost the colour almost nothing. */
7300
7378
  bg = dark
7301
- ? `color-mix(in srgb, ${color} 30%, #2c3542)`
7379
+ ? `color-mix(in srgb, ${color} 25%, #2c3542)`
7302
7380
  : `color-mix(in srgb, ${color} 10%, ${surface})`;
7303
7381
  border = dark
7304
7382
  ? `color-mix(in srgb, ${color} 85%, #ffffff)`
@@ -7306,11 +7384,16 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
7306
7384
  border_style = "solid";
7307
7385
  }
7308
7386
  if(highlight) {
7309
- border = HIGHLIGHT_COLOR;
7387
+ border = highlight_color(theme);
7310
7388
  border_style = "solid";
7311
7389
  }
7312
7390
  let title_color = dark ? "#e8eaed" : "#0f172a";
7313
- let sub_color = dark ? "#9aa4b2" : "#64748b";
7391
+ /* The topic name under the record's, at 11px, so it needs the
7392
+ * 4.5:1 of small text on the WORST tint of the palette: the old
7393
+ * greys gave 2.47 in dark and 4.28 in light. These give 4.64 and
7394
+ * 5.65, and the hierarchy stays where it belongs -- in the size
7395
+ * and the weight, not in a grey nobody can read. */
7396
+ let sub_color = dark ? "#ccd3dd" : "#556173";
7314
7397
  let shadow = dark
7315
7398
  ? "0 1px 3px rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.30)"
7316
7399
  : "0 1px 3px rgba(15,23,42,0.12), 0 1px 2px rgba(15,23,42,0.06)";
@@ -7354,7 +7437,7 @@ function build_node_innerHTML(color, theme, icon, label, topic_name, structural,
7354
7437
  background: ${bg};
7355
7438
  border: ${highlight? "3px" : "1.5px"} ${border_style} ${border};
7356
7439
  border-radius: 10px;
7357
- ${ring_shadow(highlight, selected, shadow)}
7440
+ ${ring_shadow(highlight, selected, shadow, theme)}
7358
7441
  ${anchor_outline(anchored)}
7359
7442
  color: ${title_color};
7360
7443
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
@@ -8605,9 +8688,14 @@ function pill_colors(color, theme)
8605
8688
  bg: dark
8606
8689
  ? `color-mix(in srgb, ${color} 45%, #1b2230)`
8607
8690
  : `color-mix(in srgb, ${color} 22%, #ffffff)`,
8691
+ /* The INK of a pill, a leaf chip and a `+N`: it carries the
8692
+ * topic's hue, and it is 10-12px text on the same hue. At
8693
+ * 35/55 the palette's yellow read 4.36 in dark and 3.89 in
8694
+ * light; at 25/45 the worst of the seven is 4.57 and 5.07,
8695
+ * and the hue is still plainly there. */
8608
8696
  fg: dark
8609
- ? `color-mix(in srgb, ${color} 35%, #ffffff)`
8610
- : `color-mix(in srgb, ${color} 55%, #0f172a)`,
8697
+ ? `color-mix(in srgb, ${color} 25%, #ffffff)`
8698
+ : `color-mix(in srgb, ${color} 45%, #0f172a)`,
8611
8699
  border: dark
8612
8700
  ? `color-mix(in srgb, ${color} 80%, #ffffff)`
8613
8701
  : color,
@@ -8637,7 +8725,7 @@ function build_pill_html(pill, color, theme)
8637
8725
  font-size: 10px; font-weight: 700; line-height: 1; white-space: nowrap;
8638
8726
  overflow: hidden; text-overflow: ellipsis;
8639
8727
  cursor: pointer; user-select: none;
8640
- "><span style="font-size: 9px;">${glyph}</span>${escapeHtml(pill.hook)}<span style="opacity: .75; font-weight: 600;">${count}</span></span>`;
8728
+ "><span style="font-size: 9px;">${glyph}</span>${escapeHtml(pill.hook)}<span style="font-weight: 600;">${count}</span></span>`;
8641
8729
  }
8642
8730
 
8643
8731
  /************************************************************
@@ -9068,7 +9156,11 @@ async function reconcile_fold_apply(gobj, opts, visible)
9068
9156
  sourcePort: p.hook,
9069
9157
  lineWidth: 1,
9070
9158
  lineDash: [4, 3],
9071
- stroke: dark? '#8b94a3' : '#94a3b8',
9159
+ /* The same grey as a cross link (refresh_default_edges_theme):
9160
+ * `#94a3b8` on a white canvas is 2.56:1, under the 3:1 a
9161
+ * line needs to be seen at all. The DASH is what says
9162
+ * this one leads to a cut, not the colour. */
9163
+ stroke: dark? '#8b94a3' : '#6b7280',
9072
9164
  startArrow: false,
9073
9165
  endArrow: false,
9074
9166
  },
@@ -9157,6 +9249,40 @@ function ac_language_changed(gobj, event, kw, src)
9157
9249
  return 0;
9158
9250
  }
9159
9251
 
9252
+ /************************************************************
9253
+ * The rims of every port, on a theme change.
9254
+ *
9255
+ * A rim is half of the surface it sits on (see port_rim), so it
9256
+ * belongs to the theme -- and it lives in each node's
9257
+ * `style.ports`, which is the one place refresh_html_nodes_theme()
9258
+ * does not reach: it rebuilds the html INSIDE a card.
9259
+ ************************************************************/
9260
+ function refresh_port_rims(gobj, theme)
9261
+ {
9262
+ let priv = gobj.priv;
9263
+ let graph = priv.graph;
9264
+
9265
+ if(!graph) {
9266
+ return;
9267
+ }
9268
+ let updates = [];
9269
+ for(let nd of (graph.getNodeData() || [])) {
9270
+ if(!nd || !nd.style || !is_array(nd.style.ports) || !nd.style.ports.length) {
9271
+ continue;
9272
+ }
9273
+ updates.push({id: nd.id, style: {ports: nd.style.ports.map((p) =>
9274
+ Object.assign({}, p, {stroke: port_rim(p.fill, theme)})
9275
+ )}});
9276
+ }
9277
+ if(updates.length) {
9278
+ try {
9279
+ graph.updateNodeData(updates);
9280
+ } catch(e) {
9281
+ log_error(`${gobj_short_name(gobj)}: cannot repaint the port rims: ${e}`);
9282
+ }
9283
+ }
9284
+ }
9285
+
9160
9286
  /************************************************************
9161
9287
  * Repaint the `+N` chips (theme or language changed).
9162
9288
  ************************************************************/
@@ -9680,6 +9806,7 @@ function ac_theme(gobj, event, kw, src)
9680
9806
 
9681
9807
  refresh_html_nodes_theme(gobj, theme);
9682
9808
  refresh_default_edges_theme(gobj, theme);
9809
+ refresh_port_rims(gobj, theme);
9683
9810
  repaint_more_chips(gobj);
9684
9811
 
9685
9812
  graph_draw(gobj).then(() => {