@jsenv/navi 0.29.376 → 0.29.378

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.
@@ -34174,10 +34174,18 @@ registerNaviCommand("--navi-define", (source, event) => {
34174
34174
  implementation: () => executeNaviDefine(source, event, target),
34175
34175
  };
34176
34176
  });
34177
+ // A send whose target is the popup itself: what is around the source IS the
34178
+ // popup's answer, and a picker runs its action with that answer as it closes
34179
+ // (see onRequestClose in picker_custom.jsx) — dispatching the action here too
34180
+ // would run it twice. `isSend` tells this close from a dismissal (the cross,
34181
+ // a press outside, Escape): the person pressed a choice, which a picker may
34182
+ // act on even when the choice is the one it already held.
34177
34183
  const executeNaviDefine = (source, event, target) => {
34178
- // The picker's onClose already dispatches the action with the final value.
34179
- // Dispatching again here would fire the action twice.
34180
- return triggerNaviCommand(target, "--navi-close", event);
34184
+ return dispatchCustomEvent(target, "navi_request_close", {
34185
+ event,
34186
+ source: resolveCommandProxySource(source),
34187
+ isSend: true,
34188
+ });
34181
34189
  };
34182
34190
 
34183
34191
  registerNaviCommand("--navi-scroll", (source, event) => {
@@ -44189,6 +44197,10 @@ time.navi_text {
44189
44197
  border-radius: inherit;
44190
44198
  }
44191
44199
 
44200
+ &[data-text-clamp] {
44201
+ min-width: 0;
44202
+ }
44203
+
44192
44204
  &[data-text-overflow] {
44193
44205
  text-overflow: ellipsis;
44194
44206
  overflow-wrap: normal;
@@ -44562,6 +44574,10 @@ const shouldInjectSpacingBetween = (left, right) => {
44562
44574
  * n lines. This is the only prop to use for that — `Box`'s `lineClamp` /
44563
44575
  * `overflowEllipsis` are raw CSS mappings meant for elements that are not a
44564
44576
  * `Text`, and `lineClamp={1}` is never the single-line truncation you want.
44577
+ * Either value states the `white-space` it needs — one line does not wrap,
44578
+ * n lines may — so it holds inside a single-line ancestor too (a `Picker`'s
44579
+ * value, a `Time`); an explicit `noWrap`/`pre`/`preLine` on this `Text`
44580
+ * still wins.
44565
44581
  * Truncation only happens if the element may become narrower than its
44566
44582
  * content: `maxLines` sets `min-width: 0` here, but each `Box` between this
44567
44583
  * one and the element that carries the width must set it too.
@@ -44624,6 +44640,25 @@ const shouldInjectSpacingBetween = (left, right) => {
44624
44640
  * internally for overlays such as the skeleton container.
44625
44641
  */
44626
44642
  const Text = props => {
44643
+ if (props.maxLines > 1) {
44644
+ props = {
44645
+ ...props,
44646
+ "data-text-clamp": ""
44647
+ };
44648
+ if (!saysWhiteSpace(props)) {
44649
+ // n lines means "you may wrap". white-space is inherited, so left unsaid
44650
+ // a single-line ancestor (a Picker's value, a Time) leaves the clamp one
44651
+ // line to cut, and the text runs past its box. Same tag rule as
44652
+ // TextOverflow: a paragraph keeps its line breaks.
44653
+ props = props.as === "p" ? {
44654
+ ...props,
44655
+ preLine: true
44656
+ } : {
44657
+ ...props,
44658
+ noWrap: false
44659
+ };
44660
+ }
44661
+ }
44627
44662
  if (props.loading || props.skeleton) {
44628
44663
  return jsx(TextSkeleton, {
44629
44664
  ...props
@@ -44835,6 +44870,14 @@ const TextOverflow = ({
44835
44870
  children: children
44836
44871
  });
44837
44872
  };
44873
+ const saysWhiteSpace = ({
44874
+ noWrap,
44875
+ pre,
44876
+ preWrap,
44877
+ preLine
44878
+ }) => {
44879
+ return noWrap !== undefined || pre !== undefined || preWrap !== undefined || preLine !== undefined;
44880
+ };
44838
44881
  const TextWithSelectRange = ({
44839
44882
  ref,
44840
44883
  selectRange,
@@ -58807,9 +58850,11 @@ const TimeRelative = ({
58807
58850
  });
58808
58851
  };
58809
58852
  const TimeText = props => {
58853
+ // A date stays on one line, unless the caller grants it several.
58854
+ const noWrap = props.maxLines > 1 ? undefined : true;
58810
58855
  return jsx(Text, {
58811
58856
  as: "time",
58812
- noWrap: true,
58857
+ noWrap: noWrap,
58813
58858
  ...props
58814
58859
  });
58815
58860
  };
@@ -64673,6 +64718,9 @@ const PickerCustom = props => {
64673
64718
  // closed on it. A confirm picker is the one saying something (see
64674
64719
  // picker_confirm.jsx): its press, deferred until the question is answered.
64675
64720
  onConfirm,
64721
+ // A choice pressed inside the popup runs `action` even when it is the one
64722
+ // the picker already held. See the JSDoc.
64723
+ canSendWhileUnchanged,
64676
64724
  // The popup's lifecycle, the same pair Dialog and Popover take. Taken on
64677
64725
  // the picker and chained into its own openController below: the picker
64678
64726
  // hands the popup that controller, and a controlled Dialog/Popover reads
@@ -64715,6 +64763,7 @@ const PickerCustom = props => {
64715
64763
  delete pickerProps.defaultOpen;
64716
64764
  delete pickerProps.escapeEffect;
64717
64765
  delete pickerProps.onConfirm;
64766
+ delete pickerProps.canSendWhileUnchanged;
64718
64767
  delete pickerProps.onOpen;
64719
64768
  delete pickerProps.onClose;
64720
64769
  delete pickerProps.openOn;
@@ -64814,8 +64863,17 @@ const PickerCustom = props => {
64814
64863
  // suggestion to accept, and confirming `undefined` cannot mean
64815
64864
  // anything. A picker on a defaultValue is untouched by this: it
64816
64865
  // shows something, so closing on it still confirms it.
64817
- // No action to run, but still allow the close.
64818
- return;
64866
+ //
64867
+ // Unless the close is a choice PRESSED inside the popup (a row's
64868
+ // `--navi-send`, a `--navi-confirm`) on a picker that asked to
64869
+ // send while unchanged: the person picked what was already picked,
64870
+ // and for that picker the same value said again means something.
64871
+ // A press outside, Escape, the cross say nothing and keep skipping.
64872
+ const said = requestCloseEvent.detail.isSend || confirmEventRef.current;
64873
+ if (!(canSendWhileUnchanged && said)) {
64874
+ // No action to run, but still allow the close.
64875
+ return;
64876
+ }
64819
64877
  }
64820
64878
  dispatchRequestAction(inputEl, {
64821
64879
  event: requestCloseEvent,
@@ -64998,7 +65056,8 @@ const PickerCustom = props => {
64998
65056
  intent: "read",
64999
65057
  allowed: () => {
65000
65058
  const closing = requestClose(e, {
65001
- isCancel: e.detail.isCancel
65059
+ isCancel: e.detail.isCancel,
65060
+ isSend: e.detail.isSend
65002
65061
  });
65003
65062
  if (!closing) {
65004
65063
  e.preventDefault();
@@ -76049,13 +76108,7 @@ const renderDayDefault = (day, {
76049
76108
  type: "date",
76050
76109
  format: format,
76051
76110
  dayLabel: true,
76052
- lang: lang
76053
- // A Time keeps its date on one line by default; here a day too long for
76054
- // the box is meant to wrap, so that is undone — except for maxLines={1},
76055
- // which IS one line and cuts it itself (see Text's own TextOverflow):
76056
- // saying "you may wrap" there would undo the truncation instead.
76057
- ,
76058
- noWrap: maxLines === 1 || maxLines === "1" ? undefined : false,
76111
+ lang: lang,
76059
76112
  maxLines: maxLines,
76060
76113
  children: day
76061
76114
  });