@jsenv/navi 0.29.377 → 0.29.379

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.
@@ -45318,6 +45318,10 @@ time.navi_text {
45318
45318
  border-radius: inherit;
45319
45319
  }
45320
45320
 
45321
+ &[data-text-clamp] {
45322
+ min-width: 0;
45323
+ }
45324
+
45321
45325
  &[data-text-overflow] {
45322
45326
  text-overflow: ellipsis;
45323
45327
  overflow-wrap: normal;
@@ -45691,6 +45695,10 @@ const shouldInjectSpacingBetween = (left, right) => {
45691
45695
  * n lines. This is the only prop to use for that — `Box`'s `lineClamp` /
45692
45696
  * `overflowEllipsis` are raw CSS mappings meant for elements that are not a
45693
45697
  * `Text`, and `lineClamp={1}` is never the single-line truncation you want.
45698
+ * Either value states the `white-space` it needs — one line does not wrap,
45699
+ * n lines may — so it holds inside a single-line ancestor too (a `Picker`'s
45700
+ * value, a `Time`); an explicit `noWrap`/`pre`/`preLine` on this `Text`
45701
+ * still wins.
45694
45702
  * Truncation only happens if the element may become narrower than its
45695
45703
  * content: `maxLines` sets `min-width: 0` here, but each `Box` between this
45696
45704
  * one and the element that carries the width must set it too.
@@ -45753,6 +45761,25 @@ const shouldInjectSpacingBetween = (left, right) => {
45753
45761
  * internally for overlays such as the skeleton container.
45754
45762
  */
45755
45763
  const Text = props => {
45764
+ if (props.maxLines > 1) {
45765
+ props = {
45766
+ ...props,
45767
+ "data-text-clamp": ""
45768
+ };
45769
+ if (!saysWhiteSpace(props)) {
45770
+ // n lines means "you may wrap". white-space is inherited, so left unsaid
45771
+ // a single-line ancestor (a Picker's value, a Time) leaves the clamp one
45772
+ // line to cut, and the text runs past its box. Same tag rule as
45773
+ // TextOverflow: a paragraph keeps its line breaks.
45774
+ props = props.as === "p" ? {
45775
+ ...props,
45776
+ preLine: true
45777
+ } : {
45778
+ ...props,
45779
+ noWrap: false
45780
+ };
45781
+ }
45782
+ }
45756
45783
  if (props.loading || props.skeleton) {
45757
45784
  return jsx(TextSkeleton, {
45758
45785
  ...props
@@ -45964,6 +45991,14 @@ const TextOverflow = ({
45964
45991
  children: children
45965
45992
  });
45966
45993
  };
45994
+ const saysWhiteSpace = ({
45995
+ noWrap,
45996
+ pre,
45997
+ preWrap,
45998
+ preLine
45999
+ }) => {
46000
+ return noWrap !== undefined || pre !== undefined || preWrap !== undefined || preLine !== undefined;
46001
+ };
45967
46002
  const TextWithSelectRange = ({
45968
46003
  ref,
45969
46004
  selectRange,
@@ -60001,9 +60036,11 @@ const TimeRelative = ({
60001
60036
  });
60002
60037
  };
60003
60038
  const TimeText = props => {
60039
+ // A date stays on one line, unless the caller grants it several.
60040
+ const noWrap = props.maxLines > 1 ? undefined : true;
60004
60041
  return jsx(Text, {
60005
60042
  as: "time",
60006
- noWrap: true,
60043
+ noWrap: noWrap,
60007
60044
  ...props
60008
60045
  });
60009
60046
  };
@@ -61244,6 +61281,10 @@ const ROOT_ATTRIBUTE = "data-navi-popup-lift";
61244
61281
  // What the two boxes are to each other (Dialog's `lift`: "box" | "scene"),
61245
61282
  // worn by the root too — it decides how each picture sits in the moving box.
61246
61283
  const KIND_ATTRIBUTE = "data-navi-popup-lift-kind";
61284
+ // Worn by the root when the two pictures fit the moving box the whole way
61285
+ // (see picturesFitTheBox): the box's edge then has nothing to cut but the
61286
+ // pictures' own ink — a halo, a shadow — and the CSS lets it through.
61287
+ const FIT_ATTRIBUTE = "data-navi-popup-lift-fit";
61247
61288
  // The one node that IS the anchor once in front: the popup itself, or a node
61248
61289
  // inside it.
61249
61290
  const TARGET_SELECTOR = "[data-lift]";
@@ -61363,6 +61404,7 @@ const liftPopupFromAnchor = (
61363
61404
  giveBackNameArriving?.();
61364
61405
  root.removeAttribute(ROOT_ATTRIBUTE);
61365
61406
  root.removeAttribute(KIND_ATTRIBUTE);
61407
+ root.removeAttribute(FIT_ATTRIBUTE);
61366
61408
  root.style.removeProperty(DURATION_PROPERTY);
61367
61409
  root.style.removeProperty(BORDER_RADIUS_PROPERTY);
61368
61410
  root.style.removeProperty(BACKGROUND_COLOR_PROPERTY);
@@ -61374,7 +61416,7 @@ const liftPopupFromAnchor = (
61374
61416
  releaseScrollHold?.();
61375
61417
  releaseScrollHold = trapScrollInside(popupEl, { backdrop: true });
61376
61418
  const room = measureRoomBetweenBars();
61377
- const boxLeaving = room ? elementLeaving.getBoundingClientRect() : null;
61419
+ const boxLeaving = elementLeaving.getBoundingClientRect();
61378
61420
  let boxArriving = null;
61379
61421
  let cornersArriving = null;
61380
61422
  const viewTransition = startViewTransition(async () => {
@@ -61392,8 +61434,9 @@ const liftPopupFromAnchor = (
61392
61434
  if (elementArriving) {
61393
61435
  giveBackNameArriving = wearLiftName(elementArriving);
61394
61436
  cornersArriving = readCorners(elementArriving);
61395
- if (room) {
61396
- boxArriving = elementArriving.getBoundingClientRect();
61437
+ boxArriving = elementArriving.getBoundingClientRect();
61438
+ if (picturesFitTheBox(lift, boxLeaving, boxArriving)) {
61439
+ root.setAttribute(FIT_ATTRIBUTE, "");
61397
61440
  }
61398
61441
  }
61399
61442
  });
@@ -61697,6 +61740,30 @@ const animateMovingBox = ({ cornersFrom, cornersTo, room, boxFrom, boxTo }) => {
61697
61740
  });
61698
61741
  };
61699
61742
 
61743
+ // Whether both pictures fit the moving box from one end to the other. The
61744
+ // box's clip (dialog.jsx) is its edge for a picture larger than the box: what
61745
+ // a card gaining room uncovers, what a scene shows past the band cut from it.
61746
+ // Under "box" each picture keeps its own size, so both fit only when the two
61747
+ // boxes are the same size; under "scene" both are drawn as wide as the box
61748
+ // and centred, so they fit when the two boxes have the same aspect ratio —
61749
+ // each picture, drawn at the other box's width, is then that box's height.
61750
+ // A picture's ink past its own box (a halo, a shadow) is not content the clip
61751
+ // is there to cut, so when they fit, the clip is lifted.
61752
+ const picturesFitTheBox = (lift, boxFrom, boxTo) => {
61753
+ if (lift === "scene") {
61754
+ const heightFromAtWidthTo = (boxTo.width * boxFrom.height) / boxFrom.width;
61755
+ const heightToAtWidthFrom = (boxFrom.width * boxTo.height) / boxTo.width;
61756
+ return (
61757
+ Math.abs(heightFromAtWidthTo - boxTo.height) < 1 &&
61758
+ Math.abs(heightToAtWidthFrom - boxFrom.height) < 1
61759
+ );
61760
+ }
61761
+ return (
61762
+ Math.abs(boxFrom.width - boxTo.width) < 1 &&
61763
+ Math.abs(boxFrom.height - boxTo.height) < 1
61764
+ );
61765
+ };
61766
+
61700
61767
  const insetToRoom = (room, box) =>
61701
61768
  `inset(${room.top - box.top}px ${box.right - room.right}px ${box.bottom - room.bottom}px ${room.left - box.left}px)`;
61702
61769
 
@@ -62345,6 +62412,12 @@ const css$E = /* css */`
62345
62412
  the box, and a change of width would read as the same card zooming
62346
62413
  then swapping.
62347
62414
 
62415
+ A picture holds the element's ink past its own box too — a halo, a
62416
+ shadow — and the clip cuts that along with the content, at the box's
62417
+ corners. When both pictures fit the box the whole way (popup_lift.js,
62418
+ picturesFitTheBox) there is no content to uncover, only ink to lose:
62419
+ the clip is lifted and the box carries its ink along.
62420
+
62348
62421
  The box paints what the lifted card paints behind its content
62349
62422
  (published by popup_lift.js): where it has grown past the picture it
62350
62423
  carries, it is the card that has grown. Its corners are those of the
@@ -62362,6 +62435,9 @@ const css$E = /* css */`
62362
62435
  block-size: auto;
62363
62436
  inline-size: auto;
62364
62437
  }
62438
+ &[data-navi-popup-lift-fit]::view-transition-image-pair(navi-popup-lift) {
62439
+ overflow: visible;
62440
+ }
62365
62441
 
62366
62442
  /* The card leaves as itself and arrives as what it became: the picture
62367
62443
  being left stays whole for most of the way, the arriving one only shows
@@ -76389,6 +76465,12 @@ const PickerFirstResolver = props => {
76389
76465
  * press, the way a click is the innermost target's. Being a gesture, the open goes through
76390
76466
  * the interaction gate as one: a `readOnly` picker refuses it and says so
76391
76467
  * where the finger is, whatever `openWhileReadOnly` says.
76468
+ * @param {number} [maxLines=1] How many lines the value may take before it is
76469
+ * cut with an ellipsis — `Text`'s `maxLines`, put on the value box, and
76470
+ * granted to a `BadgeList` in the `ui`, which caps its rows to it (see
76471
+ * max_lines_context.js). `variant="text"` and `variant="bare"` are not
76472
+ * clamped: their drawing is the caller's own, a `Text` in the `ui` cuts
76473
+ * itself with its own `maxLines`. See docs/typography.md.
76392
76474
  * @param {import("ignore:preact").ComponentChildren | "default" | import("ignore:preact").ComponentType} [ui] What the
76393
76475
  * trigger draws in place of the value's default rendering (a date, a list
76394
76476
  * joined by commas…) — and then all it draws: `placeholder` is not shown
@@ -78160,13 +78242,7 @@ const renderDayDefault = (day, {
78160
78242
  type: "date",
78161
78243
  format: format,
78162
78244
  dayLabel: true,
78163
- lang: lang
78164
- // A Time keeps its date on one line by default; here a day too long for
78165
- // the box is meant to wrap, so that is undone — except for maxLines={1},
78166
- // which IS one line and cuts it itself (see Text's own TextOverflow):
78167
- // saying "you may wrap" there would undo the truncation instead.
78168
- ,
78169
- noWrap: maxLines === 1 || maxLines === "1" ? undefined : false,
78245
+ lang: lang,
78170
78246
  maxLines: maxLines,
78171
78247
  children: day
78172
78248
  });