@jsenv/navi 0.29.428 → 0.29.429

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.
@@ -39814,6 +39814,16 @@ const resolveAfterSend = (target, requester) => {
39814
39814
  }
39815
39815
  return undefined;
39816
39816
  };
39817
+ // What follows a send is caused by the send, not by the gesture: the send
39818
+ // answered the gesture and may have prevented it (an Enter must not also click
39819
+ // the submit button, nor activate the trigger of the popup it closed), and a
39820
+ // follow-up judged on that event is refused as a gesture someone cancelled.
39821
+ // Chained, so the gesture stays readable behind it.
39822
+ const createSentEvent = (event) => {
39823
+ const sentEvent = new CustomEvent("sent", { detail: {} });
39824
+ chainEvent(sentEvent, event);
39825
+ return sentEvent;
39826
+ };
39817
39827
 
39818
39828
  registerNaviCommand("--navi-send", (source, event, { requester }) => {
39819
39829
  const expandable = resolveExpandableAround(source);
@@ -39846,7 +39856,9 @@ registerNaviCommand("--navi-send", (source, event, { requester }) => {
39846
39856
  source.getAttribute("data-after-send") ||
39847
39857
  target.getAttribute("data-after-send");
39848
39858
  if (afterSend) {
39849
- triggerNaviCommand(target, afterSend, event, { optional: true });
39859
+ triggerNaviCommand(target, afterSend, createSentEvent(event), {
39860
+ optional: true,
39861
+ });
39850
39862
  }
39851
39863
  return result;
39852
39864
  },
@@ -39890,7 +39902,9 @@ registerNaviCommand("--navi-send", (source, event, { requester }) => {
39890
39902
  if (!afterSend) {
39891
39903
  return;
39892
39904
  }
39893
- triggerNaviCommand(source, afterSend, event, { optional: true });
39905
+ triggerNaviCommand(source, afterSend, createSentEvent(event), {
39906
+ optional: true,
39907
+ });
39894
39908
  };
39895
39909
  const {
39896
39910
  result: sent,
@@ -74111,9 +74125,12 @@ const useListScrollSync = ({
74111
74125
  };
74112
74126
  const [renderWindow, setRenderWindow] = useState(() => {
74113
74127
  // Opening somewhere else than the beginning starts by framing there: the
74114
- // items the list will draw are the items it will ask for.
74128
+ // items the list will draw are the items it will ask for. A named item is
74129
+ // framed where it stood when it was written down, which is where holdWindow
74130
+ // aims before anyone can say where it is.
74115
74131
  const openAt = scrolled ?? defaultScrolled;
74116
- const start = typeof openAt === "number" ? openAt - itemsAboveOpening(openAt, firstWindowItemCount) : 0;
74132
+ const openIndex = typeof openAt === "number" ? openAt : openAt && typeof openAt === "object" && typeof openAt.index === "number" ? openAt.index : null;
74133
+ const start = openIndex === null ? 0 : openIndex - itemsAboveOpening(openAt, firstWindowItemCount);
74117
74134
  const startClamped = start < 0 ? 0 : start;
74118
74135
  return {
74119
74136
  start: startClamped,
@@ -74240,14 +74257,11 @@ const useListScrollSync = ({
74240
74257
  if (wantedStart < 0) {
74241
74258
  wantedStart = 0;
74242
74259
  }
74243
- if (wantedStart === start) {
74244
- listItems.holdPending = false;
74245
- return;
74246
- }
74247
- renderWindowRef.current = {
74248
- start: wantedStart,
74249
- end: wantedStart + windowSize
74250
- };
74260
+ // The window the hold frames goes into the state, not into this render
74261
+ // alone: the next render starts from the state, and once the item stands
74262
+ // inside the window the hold stops framing it — a window left where the
74263
+ // state had it would draw around another place.
74264
+ updateRenderWindow(wantedStart, wantedStart + windowSize, `held on item ${heldItem}`);
74251
74265
  listItems.holdPending = false;
74252
74266
  };
74253
74267
  const pendingScrollRef = useRef();
@@ -74396,6 +74410,13 @@ const useListScrollSync = ({
74396
74410
  return;
74397
74411
  }
74398
74412
  hasBeenDisplayedRef.current = true;
74413
+ const place = startPlaceRef.current;
74414
+ if (!place.userTookOver && place.wanted !== "start" && place.wanted !== undefined) {
74415
+ // Held somewhere: where the list opens is the hold's to say (see
74416
+ // placeWhereHeld). Scrolled here too, the list would go to the top or
74417
+ // the selected item for as long as the hold takes to put it back.
74418
+ return;
74419
+ }
74399
74420
  const items = listItems.itemsSignal.peek();
74400
74421
  const firstSelected = items.find(i => {
74401
74422
  if (i.selected) {
@@ -75098,12 +75119,14 @@ const useListScrollSync = ({
75098
75119
  const spare = budget > screen ? budget - screen : 0;
75099
75120
  const behindSize = countsItems ? Math.floor(spare / 4) : spare / 4;
75100
75121
  const aheadSize = spare - behindSize;
75101
- if (stage === "steady" && !budgetWarnedRef.current && bandEnd > bandStart) {
75102
- const twoLines = (countsItems ? 2 : 2 * (bandTo - bandFrom) / (bandEnd - bandStart)) * itemsPerLineNow;
75103
- if (spare < twoLines) {
75104
- budgetWarnedRef.current = true;
75105
- console.warn(`List: renderBudget=${renderBudget.value}${renderBudget.unit} leaves less than two ${itemsPerLineNow > 1 ? "lines of items" : "items"} beyond what the screen shows (${bandEnd - bandStart} items): items will go blank as it scrolls. Give it room for a screen ahead or more — "300%" of the box that scrolls it, say.`);
75106
- }
75122
+ // Said only when the budget holds nothing past the screen: the blank is
75123
+ // then certain. Past the screen, whether a fling outruns the window is
75124
+ // what the device and the rest of the main thread's work decide, and a
75125
+ // number of items cannot tell it — two one-line items are 76 px, two
75126
+ // cards a whole screen. That is measured on the list, not guessed here.
75127
+ if (stage === "steady" && !budgetWarnedRef.current && bandEnd > bandStart && spare === 0) {
75128
+ budgetWarnedRef.current = true;
75129
+ console.warn(`List: renderBudget=${renderBudget.value}${renderBudget.unit} holds no more than what the screen shows (${bandEnd - bandStart} items on it): the screen goes blank past it as soon as the list scrolls. Give it more than a screen — "150%" of the box that scrolls it, say.`);
75107
75130
  }
75108
75131
  if (!force) {
75109
75132
  const roomAround = readRoomAround({
@@ -78798,7 +78821,8 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
78798
78821
  * "Many rows"). The window keeps three quarters of what the screen leaves of
78799
78822
  * it ahead of the scroll, and moves once that falls under half a screen; it
78800
78823
  * has to hold more than the screen shows, with room for that lookahead — the
78801
- * list warns when it leaves less than two items beyond the screen.
78824
+ * list warns when it holds no more than the screen. How much more is
78825
+ * measured: fling the list on the slowest device it runs on.
78802
78826
  *
78803
78827
  * `{ initial, after }` for a list whose first picture is taken as it is
78804
78828
  * built — drawn in the click that opens a popup, or in the update callback