@jsenv/navi 0.29.375 → 0.29.377

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.
@@ -35096,10 +35096,18 @@ registerNaviCommand("--navi-define", (source, event) => {
35096
35096
  implementation: () => executeNaviDefine(source, event, target),
35097
35097
  };
35098
35098
  });
35099
+ // A send whose target is the popup itself: what is around the source IS the
35100
+ // popup's answer, and a picker runs its action with that answer as it closes
35101
+ // (see onRequestClose in picker_custom.jsx) — dispatching the action here too
35102
+ // would run it twice. `isSend` tells this close from a dismissal (the cross,
35103
+ // a press outside, Escape): the person pressed a choice, which a picker may
35104
+ // act on even when the choice is the one it already held.
35099
35105
  const executeNaviDefine = (source, event, target) => {
35100
- // The picker's onClose already dispatches the action with the final value.
35101
- // Dispatching again here would fire the action twice.
35102
- return triggerNaviCommand(target, "--navi-close", event);
35106
+ return dispatchCustomEvent(target, "navi_request_close", {
35107
+ event,
35108
+ source: resolveCommandProxySource(source),
35109
+ isSend: true,
35110
+ });
35103
35111
  };
35104
35112
 
35105
35113
  registerNaviCommand("--navi-scroll", (source, event) => {
@@ -66012,6 +66020,9 @@ const PickerCustom = props => {
66012
66020
  // closed on it. A confirm picker is the one saying something (see
66013
66021
  // picker_confirm.jsx): its press, deferred until the question is answered.
66014
66022
  onConfirm,
66023
+ // A choice pressed inside the popup runs `action` even when it is the one
66024
+ // the picker already held. See the JSDoc.
66025
+ canSendWhileUnchanged,
66015
66026
  // The popup's lifecycle, the same pair Dialog and Popover take. Taken on
66016
66027
  // the picker and chained into its own openController below: the picker
66017
66028
  // hands the popup that controller, and a controlled Dialog/Popover reads
@@ -66054,6 +66065,7 @@ const PickerCustom = props => {
66054
66065
  delete pickerProps.defaultOpen;
66055
66066
  delete pickerProps.escapeEffect;
66056
66067
  delete pickerProps.onConfirm;
66068
+ delete pickerProps.canSendWhileUnchanged;
66057
66069
  delete pickerProps.onOpen;
66058
66070
  delete pickerProps.onClose;
66059
66071
  delete pickerProps.openOn;
@@ -66155,8 +66167,17 @@ const PickerCustom = props => {
66155
66167
  // suggestion to accept, and confirming `undefined` cannot mean
66156
66168
  // anything. A picker on a defaultValue is untouched by this: it
66157
66169
  // shows something, so closing on it still confirms it.
66158
- // No action to run, but still allow the close.
66159
- return;
66170
+ //
66171
+ // Unless the close is a choice PRESSED inside the popup (a row's
66172
+ // `--navi-send`, a `--navi-confirm`) on a picker that asked to
66173
+ // send while unchanged: the person picked what was already picked,
66174
+ // and for that picker the same value said again means something.
66175
+ // A press outside, Escape, the cross say nothing and keep skipping.
66176
+ const said = requestCloseEvent.detail.isSend || confirmEventRef.current;
66177
+ if (!(canSendWhileUnchanged && said)) {
66178
+ // No action to run, but still allow the close.
66179
+ return;
66180
+ }
66160
66181
  }
66161
66182
  dispatchRequestAction(inputEl, {
66162
66183
  event: requestCloseEvent,
@@ -66350,7 +66371,8 @@ const PickerCustom = props => {
66350
66371
  intent: "read",
66351
66372
  allowed: () => {
66352
66373
  const closing = requestClose(e, {
66353
- isCancel: e.detail.isCancel
66374
+ isCancel: e.detail.isCancel,
66375
+ isSend: e.detail.isSend
66354
66376
  });
66355
66377
  if (!closing) {
66356
66378
  e.preventDefault();
@@ -69979,8 +70001,17 @@ const useListScrollSync = ({
69979
70001
  // The list is holding itself somewhere; that is what owns the scroll.
69980
70002
  return;
69981
70003
  }
70004
+ const scrollerEl = getScroller();
70005
+ if (scrollerEl && (horizontal ? scrollerEl.scrollLeft : scrollerEl.scrollTop) === 0) {
70006
+ // A scroller at its start has nothing above the view to keep still, and
70007
+ // rows landing above the first one are what a list read from its start
70008
+ // (a journal newest first, a feed) is there to show: holding the row on
70009
+ // top would scroll past them. The browser's own scroll anchoring makes
70010
+ // the same exception at offset 0.
70011
+ return;
70012
+ }
69982
70013
  anchorRef.current = captureScrollAnchor({
69983
- scrollerEl: getScroller(),
70014
+ scrollerEl,
69984
70015
  listEl: getListEl(),
69985
70016
  items: listRows.visibleItemsSignal.peek(),
69986
70017
  horizontal
@@ -76597,6 +76628,15 @@ const PickerFirstResolver = props => {
76597
76628
  * @param {(confirmEvent: CustomEvent) => void} [onConfirm] Called once the
76598
76629
  * popup has closed on a `--navi-confirm` said inside it. What a confirm
76599
76630
  * picker uses to run its press; a picker of any type may listen too.
76631
+ * @param {boolean} [canSendWhileUnchanged] Run `action` when a choice pressed
76632
+ * inside the popup — a row's `--navi-send`, a `--navi-confirm` — is the
76633
+ * value the picker already held. By default that close runs nothing: the
76634
+ * answer has not moved, so there is nothing new to say, same as `Form`.
76635
+ * Set this for a picker whose value is a setting that can be valid while
76636
+ * what it points to is not — a channel whose account came unlinked — so
76637
+ * picking it again is how the person asks for it to be put right, and the
76638
+ * action sees the same value and re-asks what there is to re-ask. A press
76639
+ * outside, Escape and the cross still send nothing: nothing was pressed.
76600
76640
  * @param {(openEvent: CustomEvent) => void} [onOpen] Called when the popup
76601
76641
  * opens, whatever asked for it (a press, a command, history bringing it
76602
76642
  * back). You most likely do NOT need this pair: "the user validated" is
@@ -87705,7 +87745,10 @@ const css$8 = /* css */`@layer navi {
87705
87745
  background-color: var(--x-fill-color);
87706
87746
  border-width: var(--border-width);
87707
87747
  border-radius: inherit;
87708
- clip-path: inset(0 calc((1 - var(--x-fill-ratio, 0)) * 100%) 0 0);
87748
+ clip-path: inset(0
87749
+ calc(100% - var(--border-width) - var(--x-fill-ratio, 0) *
87750
+ (100% - var(--border-width) * 2))
87751
+ 0 0);
87709
87752
  border-style: solid;
87710
87753
  border-color: #0000;
87711
87754
  position: absolute;
@@ -87753,7 +87796,8 @@ const css$8 = /* css */`@layer navi {
87753
87796
 
87754
87797
  &[data-fill-round] {
87755
87798
  & .navi_meter_fill {
87756
- width: calc(var(--x-fill-ratio) * 100%);
87799
+ width: calc(var(--x-fill-ratio) * (100% - var(--border-width) * 2) +
87800
+ var(--border-width) * 2);
87757
87801
  clip-path: unset;
87758
87802
  }
87759
87803
  }