@jsenv/navi 0.29.123 → 0.29.125

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.
@@ -50673,6 +50673,11 @@ const SlideContainer = ({
50673
50673
  }
50674
50674
  const track = trackRef.current;
50675
50675
  const offset = `${-currentPlace.x * 100}% ${-currentPlace.y * 100}%`;
50676
+ // The travel that was ASKED for is still one box, whatever is left of it to
50677
+ // cover: a slide dragged most of the way there finishes in what is left of
50678
+ // the duration rather than taking a full one over a few pixels.
50679
+ const offsetTargetBefore = offsetRef.current;
50680
+ const targetMoves = offset !== offsetTargetBefore;
50676
50681
  // Where the track IS, read before anything is written: a travel asked for
50677
50682
  // while another is still playing must carry on from what is on screen. The
50678
50683
  // previous TARGET is where the last travel was going, not where it got to —
@@ -50683,22 +50688,36 @@ const SlideContainer = ({
50683
50688
  // var just below) and not the moving one — the animation being replaced
50684
50689
  // does not contribute to it. So the position on screen is a thing to go and
50685
50690
  // fetch, and having it in hand is also what allows the pace below.
50691
+ // Measured off the box, in px, and not read off the computed `translate`:
50692
+ // see trackOffsetPx for what that value looks like mid-animation.
50686
50693
  const travelInFlight = trackAnimationRef.current?.playState === "running";
50687
- const offsetOnScreen = travelInFlight ? getComputedStyle(track).translate : undefined;
50694
+ let offsetOnScreen;
50695
+ if (travelInFlight) {
50696
+ const onScreenPx = trackOffsetPx(track, containerRef.current);
50697
+ offsetOnScreen = `${onScreenPx.x}px ${onScreenPx.y}px`;
50698
+ }
50688
50699
  // …and where a slide let go of halfway was left, which is the same fact
50689
50700
  // said by the gesture that put it there: the track is at rest as far as any
50690
- // animation is concerned, so nothing else could tell.
50691
- const offsetDragged = travelFromRef.current;
50692
- travelFromRef.current = null;
50701
+ // animation is concerned, so nothing else could tell. Taken by the render
50702
+ // that moves the track and by no other: a `current` held outside catches up
50703
+ // with the gesture a render late (a parent's state, set from a handler that
50704
+ // runs after the address is written and read back), and a render still
50705
+ // standing on the slide being left would otherwise carry the finger's
50706
+ // offset back to it — a travel home nobody asked for.
50707
+ const offsetDragged = targetMoves ? travelFromRef.current : null;
50708
+ if (targetMoves) {
50709
+ travelFromRef.current = null;
50710
+ }
50693
50711
  const offsetBefore = offsetDragged ?? offsetOnScreen ?? offsetRef.current;
50694
- // The travel that was ASKED for is still one box, whatever is left of it to
50695
- // cover: a slide dragged most of the way there finishes in what is left of
50696
- // the duration rather than taking a full one over a few pixels.
50697
- const offsetTargetBefore = offsetRef.current;
50698
50712
  offsetRef.current = offset;
50699
50713
  // Where the track ends up, always — the animation below only covers the way
50700
- // there, and when it is over this is what holds.
50701
- track.style.setProperty("--slide-container-offset", offset);
50714
+ // there, and when it is over this is what holds. Except under a hand-off
50715
+ // still waiting for its travel: the track stays where the finger left it,
50716
+ // until the render that moves it or the frame after which the gesture gives
50717
+ // up on it (see returnToRest in onEnd).
50718
+ if (!travelFromRef.current) {
50719
+ track.style.setProperty("--slide-container-offset", offset);
50720
+ }
50702
50721
  // A travel to this very offset is already playing: left to play. Same
50703
50722
  // courtesy as the stage above — a re-render in the middle of a travel (a
50704
50723
  // signal read higher up answering) changes nothing here, and setting off
@@ -50974,19 +50993,21 @@ const SlideContainer = ({
50974
50993
  return true;
50975
50994
  };
50976
50995
 
50977
- // The caller learns where the container went: the bound signal is written and
50978
- // `onCurrentChange` is called, in that order, so a caller reading the signal
50979
- // from inside its own handler reads where it now is.
50996
+ // The caller learns where the container went: the bound signal is written,
50997
+ // then the address, then `onCurrentChange` is called in that order, so a
50998
+ // caller reading either from inside its own handler reads where it now is.
50999
+ // The signal before the address because writing the address can render on
51000
+ // the spot (a navigation lets go of what Preact had queued, see
51001
+ // rendering_hold.js), and that render must already find `current` moved.
50980
51002
  const tellCurrentChange = (area, detail, leftArea) => {
50981
- // The address first, because it is the one thing that must never disagree
50982
- // with the picture — and it is told here rather than by the caller so that
50983
- // it is told about the travels that HAPPENED and about no others: the ones
50984
- // a lock refused never reach this point, and one refused late is written
50985
- // back below (see goBackToRefusedArea).
50986
- writeUrlParam(area, detail.cause);
50987
51003
  if (currentSignal) {
50988
51004
  currentSignal.value = area;
50989
51005
  }
51006
+ // The address is told here rather than by the caller so that it is told
51007
+ // about the travels that HAPPENED and about no others: the ones a lock
51008
+ // refused never reach this point, and one refused late is written back
51009
+ // below (see goBackToRefusedArea).
51010
+ writeUrlParam(area, detail.cause);
50990
51011
  if (!onCurrentChange) {
50991
51012
  return;
50992
51013
  }
@@ -51778,9 +51799,10 @@ const SlideContainer = ({
51778
51799
  returnToRest(drag);
51779
51800
  return;
51780
51801
  }
51781
- // A container whose `current` is held outside and was not moved:
51782
- // nothing rendered, so nothing drew the travel and the track is still
51783
- // under where the finger left it. One frame is all it takes to know.
51802
+ // A container whose `current` is held outside and was not moved: no
51803
+ // render moved the track, so the hand-off is still waiting and the
51804
+ // track still under where the finger left it. One frame is all it
51805
+ // takes to know.
51784
51806
  requestAnimationFrame(() => {
51785
51807
  if (travelFromRef.current) {
51786
51808
  travelFromRef.current = null;
@@ -54479,6 +54501,27 @@ const sizeOf = (element, axis) => {
54479
54501
  const translateOf = (axis, distance) =>
54480
54502
  axis === "x" ? `${distance}px 0px` : `0px ${distance}px`;
54481
54503
 
54504
+ const PopupClose = ({
54505
+ label,
54506
+ ...rest
54507
+ }) => {
54508
+ return jsx(Button, {
54509
+ command: "--navi-close",
54510
+ icon: true,
54511
+ variant: "discrete"
54512
+ // The cross is drawn at the control size, which is a few millimetres
54513
+ // wide; the padding is what makes it a target a thumb can hit.
54514
+ ,
54515
+ paddingX: "s",
54516
+ paddingY: "s",
54517
+ "aria-label": label === undefined ? naviI18n("button.close") : label,
54518
+ ...rest,
54519
+ children: jsx(Icon, {
54520
+ children: jsx(CloseSvg, {})
54521
+ })
54522
+ });
54523
+ };
54524
+
54482
54525
  installImportMetaCssBuild(import.meta);/**
54483
54526
  * A dialog is a surface, not a control: it holds no value, has no action and
54484
54527
  * aggregates nothing. Fields and a submit go in a `<Form>` inside it, exactly
@@ -56074,6 +56117,7 @@ const DIALOG_STYLE_CSS_VARS = {
56074
56117
  minHeight: "--dialog-min-height",
56075
56118
  maxHeight: "--dialog-max-height"
56076
56119
  };
56120
+ Dialog.Close = PopupClose;
56077
56121
 
56078
56122
  installImportMetaCssBuild(import.meta);/**
56079
56123
  * A popover is a surface, not a control: it holds no value, has no action and
@@ -57600,6 +57644,8 @@ const resolvePositionAreaAndAnimationKind = ({
57600
57644
  // popup_shared.js — same helpers Dialog's own custom renderer needs, no
57601
57645
  // Popover-specific knowledge in either.
57602
57646
 
57647
+ Popover.Close = PopupClose;
57648
+
57603
57649
  installImportMetaCssBuild(import.meta);/**
57604
57650
  * A lightweight version of picker_custom.jsx's own Popover/Dialog switch —
57605
57651
  * no picker concepts (value/action tracking, keyboard letter/arrow-to-open
@@ -57808,6 +57854,7 @@ const Popup = props => {
57808
57854
  children: childrenWithMode
57809
57855
  });
57810
57856
  };
57857
+ Popup.Close = PopupClose;
57811
57858
 
57812
57859
  installImportMetaCssBuild(import.meta);const css$B = /* css */`
57813
57860
  .navi_picker {
@@ -66778,6 +66825,13 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`
66778
66825
  --picker-background-color-readonly: var(--picker-background-color);
66779
66826
  --picker-background-color-disabled: var(--picker-background-color);
66780
66827
  --x-picker-icon-color: currentColor;
66828
+
66829
+ /* The value holds nothing but the icon, so it takes the icon's width
66830
+ rather than the box's: the box's justify-content is then what places
66831
+ it, and alignX means something. */
66832
+ .navi_picker_value {
66833
+ flex-grow: 0;
66834
+ }
66781
66835
  }
66782
66836
  /* discrete: no box at rest, a background on hover — the same word Button
66783
66837
  uses, and the same drawing. What is read is the value, not the field
@@ -66902,7 +66956,7 @@ const PickerButton = props => {
66902
66956
  rightSlot,
66903
66957
  placeholder,
66904
66958
  ui,
66905
- maxLines = 1,
66959
+ maxLines: maxLinesProp = 1,
66906
66960
  // By default the popover is at least as wide as the trigger (min-width:
66907
66961
  // --anchor-width). Set true when the CONTENT should dictate the popover width
66908
66962
  // (e.g. a Wheel) instead of being stretched to the trigger — see
@@ -66921,6 +66975,10 @@ const PickerButton = props => {
66921
66975
  readOnly,
66922
66976
  error
66923
66977
  } = props;
66978
+ // A word in a sentence is never truncated — and the clamp's overflow: hidden
66979
+ // would cut its dotted underline, which sits on the edge of the line box
66980
+ // (WebKit drops it or not depending on the subpixel position of the line).
66981
+ const maxLines = variant === "text" ? undefined : maxLinesProp;
66924
66982
  const isSingleLine = maxLines === 1;
66925
66983
  // Same rule as the root: phrasing content inside a sentence.
66926
66984
  const ContentTag = variant === "text" ? "span" : "div";
@@ -67040,10 +67098,6 @@ const PickerButton = props => {
67040
67098
  ,
67041
67099
 
67042
67100
  ui: ui,
67043
- onFocus: e => {
67044
- inputProps.onFocus?.(e);
67045
- e.target.select();
67046
- },
67047
67101
  onCopy: e => {
67048
67102
  const pickerEl = ref.current;
67049
67103
  if (isWithinPickerContent(e.target, pickerEl)) {