@nevescloud/pip 3.4.0 → 3.4.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/pip-core.esm.js +12 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nevescloud/pip",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "description": "Floating assistant bubble + panel + chat runtime. ESM, no build.",
5
5
  "type": "module",
6
6
  "main": "pip-core.esm.js",
package/pip-core.esm.js CHANGED
@@ -2039,10 +2039,11 @@ export function createPip(opts = {}) {
2039
2039
  slashList.innerHTML = "";
2040
2040
  if (!slashCurrent.length) { slashList.hidden = true; scroll.classList.remove("is-backdrop"); return; }
2041
2041
  scroll.classList.add("is-backdrop");
2042
+ let selectedLi = null;
2042
2043
  slashCurrent.forEach((item, i) => {
2043
2044
  const li = document.createElement("li");
2044
2045
  li.setAttribute("role", "option");
2045
- if (i === slashSelected) li.classList.add("selected");
2046
+ if (i === slashSelected) { li.classList.add("selected"); selectedLi = li; }
2046
2047
  const name = document.createElement("span");
2047
2048
  name.className = "name";
2048
2049
  name.textContent = item.isArg ? item.name : `/${item.name}`;
@@ -2054,10 +2055,12 @@ export function createPip(opts = {}) {
2054
2055
  li.appendChild(desc);
2055
2056
  }
2056
2057
  // Mouse hover promotes the row to the keyboard selection so Enter
2057
- // and arrow keys always agree with the visible highlight. Without
2058
- // this, hover and keyboard-cursor can land on different rows and
2059
- // the user can't predict which one Enter will pick.
2060
- li.addEventListener("mouseenter", () => {
2058
+ // and arrow keys agree with the visible highlight. Listen on
2059
+ // mousemove (not mouseenter) so a stationary cursor doesn't grab
2060
+ // selection when the keyboard scrolls a new row under it — the
2061
+ // re-render replaces the DOM, which would re-fire mouseenter on
2062
+ // the new element under the cursor and undo the arrow keypress.
2063
+ li.addEventListener("mousemove", () => {
2061
2064
  if (slashSelected === i) return;
2062
2065
  slashSelected = i;
2063
2066
  for (const sib of slashList.children) sib.classList.remove("selected");
@@ -2071,6 +2074,10 @@ export function createPip(opts = {}) {
2071
2074
  slashList.appendChild(li);
2072
2075
  });
2073
2076
  slashList.hidden = false;
2077
+ // Keep the keyboard-driven selection in view. block:"nearest" only
2078
+ // scrolls when the selected row is actually clipped — no jarring
2079
+ // re-center when it's already visible.
2080
+ selectedLi?.scrollIntoView({ block: "nearest" });
2074
2081
  }
2075
2082
 
2076
2083
  function closeSlashSuggest() {