@jsenv/navi 0.29.95 → 0.29.97

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.
@@ -38,7 +38,7 @@ installImportMetaCssBuild(import.meta);/**
38
38
  * any of these, and a number is the last resort, not the first tool.
39
39
  */
40
40
 
41
- const css$13 = /* css */`
41
+ const css$14 = /* css */`
42
42
  @layer navi {
43
43
  :root {
44
44
  /* A control that overlaps its neighbours (the members of a Group share
@@ -92,7 +92,7 @@ const css$13 = /* css */`
92
92
  }
93
93
  }
94
94
  `;
95
- import.meta.css = [css$13, "@jsenv/navi/src/navi_z_indexes.js"];
95
+ import.meta.css = [css$14, "@jsenv/navi/src/navi_z_indexes.js"];
96
96
 
97
97
  const addIntoArray = (array, ...valuesToAdd) => {
98
98
  if (valuesToAdd.length === 1) {
@@ -361,7 +361,7 @@ installImportMetaCssBuild(import.meta);/**
361
361
  * the very first render and the browser does everything on its own.
362
362
  */
363
363
  const URL_TARGET_ATTRIBUTE = "data-url-target";
364
- const css$12 = /* css */`
364
+ const css$13 = /* css */`
365
365
  @layer navi {
366
366
  [${URL_TARGET_ATTRIBUTE}] {
367
367
  animation: navi_url_target var(--navi-url-target-duration, 2000ms)
@@ -379,7 +379,7 @@ const css$12 = /* css */`
379
379
  }
380
380
  }
381
381
  `;
382
- import.meta.css = [css$12, "@jsenv/navi/src/nav/url_target/url_target.js"];
382
+ import.meta.css = [css$13, "@jsenv/navi/src/nav/url_target/url_target.js"];
383
383
  let urlTargetOptions = {
384
384
  block: "start",
385
385
  behavior: "instant",
@@ -6403,7 +6403,7 @@ installImportMetaCssBuild(import.meta);/**
6403
6403
  * - Arrow automatically shows when pointing at a valid anchor element
6404
6404
  * - Centers in viewport when no anchor element provided or anchor is too big
6405
6405
  */
6406
- const css$11 = /* css */`
6406
+ const css$12 = /* css */`
6407
6407
  @layer navi {
6408
6408
  .navi_callout {
6409
6409
  /* A callout is parented to what it explains, so it inherits from it — and
@@ -6646,7 +6646,7 @@ const openCallout = (message, {
6646
6646
  skipFocus = false,
6647
6647
  debug = () => {}
6648
6648
  } = {}) => {
6649
- import.meta.css = [css$11, "@jsenv/navi/src/control/rules/callout/callout.js"];
6649
+ import.meta.css = [css$12, "@jsenv/navi/src/control/rules/callout/callout.js"];
6650
6650
  if (debug === true) {
6651
6651
  debug = (e, ...args) => console.debug(`"${e.type}" -> `, ...args);
6652
6652
  }
@@ -18873,7 +18873,7 @@ const setupNetworkMonitoring = () => {
18873
18873
  };
18874
18874
  setupNetworkMonitoring();
18875
18875
 
18876
- installImportMetaCssBuild(import.meta);const css$10 = /* css */`
18876
+ installImportMetaCssBuild(import.meta);const css$11 = /* css */`
18877
18877
  .navi_loading_indicator_fluid_container {
18878
18878
  position: relative;
18879
18879
  display: flex;
@@ -18905,7 +18905,7 @@ const LoadingIndicatorFluid = ({
18905
18905
  visuallyHidden,
18906
18906
  ...rest
18907
18907
  }) => {
18908
- import.meta.css = [css$10, "@jsenv/navi/src/graphic/loading/loading_indicator_fluid.jsx"];
18908
+ import.meta.css = [css$11, "@jsenv/navi/src/graphic/loading/loading_indicator_fluid.jsx"];
18909
18909
  const ref = useRef(null);
18910
18910
  // The container dimensions can be deduced from the ref itself as the indicator is absolute inset 0
18911
18911
  const [containerWidth, setContainerWidth] = useState(0);
@@ -19110,7 +19110,7 @@ const LoadingRectangleSvg = ({
19110
19110
  });
19111
19111
  };
19112
19112
 
19113
- installImportMetaCssBuild(import.meta);const css$$ = /* css */`
19113
+ installImportMetaCssBuild(import.meta);const css$10 = /* css */`
19114
19114
  .navi_loading_outline_wrapper {
19115
19115
  position: absolute;
19116
19116
  /* Controls place the outline slightly outside their box, right on top of
@@ -19147,7 +19147,7 @@ installImportMetaCssBuild(import.meta);const css$$ = /* css */`
19147
19147
  }
19148
19148
  `;
19149
19149
  const LoadingOutline = props => {
19150
- import.meta.css = [css$$, "@jsenv/navi/src/graphic/loading/loading_outline.jsx"];
19150
+ import.meta.css = [css$10, "@jsenv/navi/src/graphic/loading/loading_outline.jsx"];
19151
19151
  if (props.containerRef) {
19152
19152
  const container = props.containerRef.current;
19153
19153
  if (!container) {
@@ -19437,7 +19437,7 @@ const selectByTextStrings = (element, range, startText, endText) => {
19437
19437
  };
19438
19438
 
19439
19439
  installImportMetaCssBuild(import.meta);// https://jsfiddle.net/v5xzJ/4/
19440
- const css$_ = /* css */`
19440
+ const css$$ = /* css */`
19441
19441
  @layer navi {
19442
19442
  .navi_text {
19443
19443
  &[data-skeleton] {
@@ -19958,7 +19958,7 @@ const TextShrinkWrap = props => {
19958
19958
  });
19959
19959
  };
19960
19960
  const TextUI = props => {
19961
- import.meta.css = [css$_, "@jsenv/navi/src/text/text.jsx"];
19961
+ import.meta.css = [css$$, "@jsenv/navi/src/text/text.jsx"];
19962
19962
  let {
19963
19963
  ref,
19964
19964
  spacing,
@@ -24717,6 +24717,16 @@ const useUIGroupStateController = (
24717
24717
  // between them, from here on.
24718
24718
  controller.stateGivenFromAbove = false;
24719
24719
  if (resolvedDistributeChildStates) {
24720
+ if (compareTwoJsValues(groupUIState, controller.uiState)) {
24721
+ // The aggregate answered what the group already holds, which is
24722
+ // how such a group says "not yet, ask me again". Some gestures
24723
+ // cannot avoid an in-between — two people swapping seats means one
24724
+ // leaves before the other arrives — and the aggregate is where
24725
+ // that half-state is recognised. Placing the children from it
24726
+ // would undo the half of the gesture that has already landed, and
24727
+ // publishing it would hand a half-answer to the row above.
24728
+ return;
24729
+ }
24720
24730
  // A group answering for all its children at once holds ONE answer
24721
24731
  // its children are views OF, rather than a value that IS what they
24722
24732
  // said: a list saying who plays and four seats saying who sits
@@ -27396,7 +27406,7 @@ const getAssociatedLabels = element => {
27396
27406
  return Array.from(element.labels);
27397
27407
  };
27398
27408
 
27399
- installImportMetaCssBuild(import.meta);const css$Z = /* css */`
27409
+ installImportMetaCssBuild(import.meta);const css$_ = /* css */`
27400
27410
  @layer navi {
27401
27411
  .navi_button {
27402
27412
  --button-border-radius: var(--navi-control-border-radius);
@@ -27827,7 +27837,7 @@ installImportMetaCssBuild(import.meta);const css$Z = /* css */`
27827
27837
  }
27828
27838
  `;
27829
27839
  const ButtonUI = props => {
27830
- import.meta.css = [css$Z, "@jsenv/navi/src/control/input/button_ui.jsx"];
27840
+ import.meta.css = [css$_, "@jsenv/navi/src/control/input/button_ui.jsx"];
27831
27841
  const {
27832
27842
  ref,
27833
27843
  // href/link
@@ -29538,7 +29548,7 @@ installImportMetaCssBuild(import.meta);/**
29538
29548
  * reaches the real container.
29539
29549
  */
29540
29550
  let openLocalDialogCount = 0;
29541
- const css$Y = /* css */`
29551
+ const css$Z = /* css */`
29542
29552
  @layer navi {
29543
29553
  .navi_dialog {
29544
29554
  /* Min gap between the dialog and the edges of its container. Written
@@ -30122,7 +30132,7 @@ const css$Y = /* css */`
30122
30132
  * @param {import("ignore:preact").ComponentChildren} props.children
30123
30133
  */
30124
30134
  const Dialog = props => {
30125
- import.meta.css = [css$Y, "@jsenv/navi/src/layout/dialog.jsx"];
30135
+ import.meta.css = [css$Z, "@jsenv/navi/src/layout/dialog.jsx"];
30126
30136
  if (props.openController) {
30127
30137
  return jsx(ControlledDialog, {
30128
30138
  ...props
@@ -31114,7 +31124,7 @@ installImportMetaCssBuild(import.meta);/**
31114
31124
  * and applied.
31115
31125
  */
31116
31126
  let openLocalPopoverCount = 0;
31117
- const css$X = /* css */`
31127
+ const css$Y = /* css */`
31118
31128
  @layer navi {
31119
31129
  .navi_popover {
31120
31130
  /* soft: user-configurable preferred max-height. Kept as a *default*
@@ -31570,7 +31580,7 @@ const css$X = /* css */`
31570
31580
  * @param {import("ignore:preact").ComponentChildren} props.children
31571
31581
  */
31572
31582
  const Popover = props => {
31573
- import.meta.css = [css$X, "@jsenv/navi/src/layout/popover.jsx"];
31583
+ import.meta.css = [css$Y, "@jsenv/navi/src/layout/popover.jsx"];
31574
31584
  if (props.openController) {
31575
31585
  return jsx(ControlledPopover, {
31576
31586
  ...props
@@ -32598,7 +32608,7 @@ installImportMetaCssBuild(import.meta);/**
32598
32608
  * event, and a caller replacing the body entirely then has one protocol to
32599
32609
  * follow — `--navi-confirm` for yes, anything that closes for no.
32600
32610
  */
32601
- const css$W = /* css */`
32611
+ const css$X = /* css */`
32602
32612
  /* The width lives on the body rather than on the popup, so that custom
32603
32613
  content (which replaces this body entirely) sizes itself instead of
32604
32614
  inheriting a ceiling meant for a sentence-long question. */
@@ -32735,7 +32745,7 @@ const ConfirmPopup = ({
32735
32745
  onAnswer,
32736
32746
  onClosed
32737
32747
  }) => {
32738
- import.meta.css = [css$W, "@jsenv/navi/src/action/confirm_popup.jsx"];
32748
+ import.meta.css = [css$X, "@jsenv/navi/src/action/confirm_popup.jsx"];
32739
32749
  const {
32740
32750
  mode,
32741
32751
  confirmLabel,
@@ -32819,7 +32829,7 @@ const defaultBody = (message, {
32819
32829
  });
32820
32830
  };
32821
32831
 
32822
- installImportMetaCssBuild(import.meta);const css$V = /* css */`
32832
+ installImportMetaCssBuild(import.meta);const css$W = /* css */`
32823
32833
  .action_error {
32824
32834
  margin-top: 0;
32825
32835
  margin-bottom: 20px;
@@ -32844,7 +32854,7 @@ const ActionRenderer = ({
32844
32854
  children,
32845
32855
  disabled
32846
32856
  }) => {
32847
- import.meta.css = [css$V, "@jsenv/navi/src/action/action_renderer.jsx"];
32857
+ import.meta.css = [css$W, "@jsenv/navi/src/action/action_renderer.jsx"];
32848
32858
  if (action === undefined) {
32849
32859
  throw new Error("ActionRenderer requires an action to render, but none was provided.");
32850
32860
  }
@@ -38588,7 +38598,7 @@ const ROUTE_TRAVEL_ATTRIBUTE = "data-navi-route-travel";
38588
38598
  // the root pictures must NOT move (they carry the whole viewport, blank bands
38589
38599
  // included).
38590
38600
 
38591
- const css$U = /* css */`
38601
+ const css$V = /* css */`
38592
38602
  /* The marked region is a picture of its own for the length of a transition of
38593
38603
  OURS, and only then — the name is what makes the pages a picture the
38594
38604
  movement below can carry.
@@ -39017,7 +39027,7 @@ const RouteTransitionArea = ({
39017
39027
  children,
39018
39028
  ...rest
39019
39029
  }) => {
39020
- import.meta.css = [css$U, "@jsenv/navi/src/nav/route_transition.jsx"];
39030
+ import.meta.css = [css$V, "@jsenv/navi/src/nav/route_transition.jsx"];
39021
39031
  const props = {
39022
39032
  ...rest,
39023
39033
  [TRANSITION_AREA_ATTRIBUTE]: ""
@@ -39074,7 +39084,7 @@ const RouteTransitionArea = ({
39074
39084
  * @returns {() => void} remove this relation.
39075
39085
  */
39076
39086
  const defineRouteTransition = (from, to, transition) => {
39077
- import.meta.css = [css$U, "@jsenv/navi/src/nav/route_transition.jsx"];
39087
+ import.meta.css = [css$V, "@jsenv/navi/src/nav/route_transition.jsx"];
39078
39088
  const {
39079
39089
  type,
39080
39090
  duration
@@ -39110,7 +39120,7 @@ const defineRouteTransition = (from, to, transition) => {
39110
39120
  * @returns {() => void} remove this default.
39111
39121
  */
39112
39122
  const defineRouteDefaultTransition = transition => {
39113
- import.meta.css = [css$U, "@jsenv/navi/src/nav/route_transition.jsx"];
39123
+ import.meta.css = [css$V, "@jsenv/navi/src/nav/route_transition.jsx"];
39114
39124
  const value = normalizeTransition(transition);
39115
39125
  defaultTransition = value;
39116
39126
  return () => {
@@ -39711,7 +39721,7 @@ const DRAGGED_ATTRIBUTE = "data-navi-route-travel-dragged";
39711
39721
  const TURNED_ATTRIBUTE = "data-navi-route-travel-turned";
39712
39722
  // The name the box wears while it travels, and only then (see nameForTravel).
39713
39723
  const TRAVEL_NAME = "navi-route-travel";
39714
- const css$T = /* css */`
39724
+ const css$U = /* css */`
39715
39725
  /* The name that makes the page inside this box a picture of its own during a
39716
39726
  transition — rather than part of the one big picture the document takes, so
39717
39727
  the two pages can move past each other while everything else stays where it
@@ -40101,7 +40111,7 @@ const RouteTravel = ({
40101
40111
  children,
40102
40112
  ...rest
40103
40113
  }) => {
40104
- import.meta.css = [css$T, "@jsenv/navi/src/nav/route_travel.jsx"];
40114
+ import.meta.css = [css$U, "@jsenv/navi/src/nav/route_travel.jsx"];
40105
40115
  const elementRef = useRef();
40106
40116
  const gestureRef = useRef(null);
40107
40117
  // The travel in hand: the transition keeping the picture of the page being
@@ -42663,7 +42673,7 @@ const PhoneSvg = () => {
42663
42673
  };
42664
42674
 
42665
42675
  installImportMetaCssBuild(import.meta);// # TextAnchor — how it works
42666
- const css$S = /* css */`
42676
+ const css$T = /* css */`
42667
42677
  .navi_text_anchor {
42668
42678
  vertical-align: baseline;
42669
42679
  user-select: none;
@@ -42698,7 +42708,7 @@ const TextAnchor = ({
42698
42708
  textSize,
42699
42709
  lineLayout
42700
42710
  }) => {
42701
- import.meta.css = [css$S, "@jsenv/navi/src/text/text_anchor.jsx"];
42711
+ import.meta.css = [css$T, "@jsenv/navi/src/text/text_anchor.jsx"];
42702
42712
  const anchorRef = useRef();
42703
42713
 
42704
42714
  // Plain useLayoutEffect would also fire while an ancestor dialog/popover
@@ -42813,7 +42823,7 @@ const computeTopOffset = ({
42813
42823
  };
42814
42824
  const charTopCanvas = document.createElement("canvas");
42815
42825
 
42816
- installImportMetaCssBuild(import.meta);const css$R = /* css */`
42826
+ installImportMetaCssBuild(import.meta);const css$S = /* css */`
42817
42827
  @layer navi {
42818
42828
  /* Ensure data attributes from box.jsx can win to update display */
42819
42829
  .navi_icon {
@@ -42971,7 +42981,7 @@ const Icon = ({
42971
42981
  fillLine,
42972
42982
  ...props
42973
42983
  }) => {
42974
- import.meta.css = [css$R, "@jsenv/navi/src/text/icon.jsx"];
42984
+ import.meta.css = [css$S, "@jsenv/navi/src/text/icon.jsx"];
42975
42985
  const innerChildren = href ? jsx("svg", {
42976
42986
  width: "100%",
42977
42987
  height: "100%",
@@ -43133,7 +43143,7 @@ const useDimColorWhen = (elementRef, shouldDim) => {
43133
43143
  });
43134
43144
  };
43135
43145
 
43136
- installImportMetaCssBuild(import.meta);const css$Q = /* css */`
43146
+ installImportMetaCssBuild(import.meta);const css$R = /* css */`
43137
43147
  @layer navi {
43138
43148
  .navi_link {
43139
43149
  --link-border-radius: unset;
@@ -43595,7 +43605,7 @@ Object.assign(PSEUDO_CLASSES, {
43595
43605
  * @param {boolean} [props.readOnly]
43596
43606
  */
43597
43607
  const Link = props => {
43598
- import.meta.css = [css$Q, "@jsenv/navi/src/nav/link/link.jsx"];
43608
+ import.meta.css = [css$R, "@jsenv/navi/src/nav/link/link.jsx"];
43599
43609
  if (props.route) {
43600
43610
  return jsx(LinkWithRoute, {
43601
43611
  ...props
@@ -43918,7 +43928,7 @@ installImportMetaCssBuild(import.meta);/**
43918
43928
  * https://dribbble.com/search/tabs
43919
43929
  */
43920
43930
  let navCount = 0;
43921
- const css$P = /* css */`
43931
+ const css$Q = /* css */`
43922
43932
  @layer navi {
43923
43933
  .navi_nav {
43924
43934
  --nav-border: none;
@@ -44201,7 +44211,7 @@ const Nav = ({
44201
44211
  slideContainer,
44202
44212
  ...props
44203
44213
  }) => {
44204
- import.meta.css = [css$P, "@jsenv/navi/src/nav/link/nav.jsx"];
44214
+ import.meta.css = [css$Q, "@jsenv/navi/src/nav/link/nav.jsx"];
44205
44215
  const defaultRef = useRef();
44206
44216
  props.ref = props.ref || defaultRef;
44207
44217
  const navRef = props.ref;
@@ -44728,7 +44738,7 @@ installImportMetaCssBuild(import.meta);/**
44728
44738
  * Border width participates in layout (it is added to the tab and page
44729
44739
  * padding): a thick border grows the binder rather than eating into the text.
44730
44740
  */
44731
- const css$O = /* css */`
44741
+ const css$P = /* css */`
44732
44742
  @layer navi {
44733
44743
  .navi_binder {
44734
44744
  --binder-border-width: var(--navi-control-border-width);
@@ -45041,7 +45051,7 @@ const Binder = ({
45041
45051
  pagePadding,
45042
45052
  ...props
45043
45053
  }) => {
45044
- import.meta.css = [css$O, "@jsenv/navi/src/nav/binder/binder.jsx"];
45054
+ import.meta.css = [css$P, "@jsenv/navi/src/nav/binder/binder.jsx"];
45045
45055
  const items = toChildArray(children).map((child, index) => {
45046
45056
  const {
45047
45057
  value: itemValue,
@@ -45528,7 +45538,7 @@ installImportMetaCssBuild(import.meta);/**
45528
45538
  * added to the size asked for exactly like the notch inset is, so the
45529
45539
  * content still gets the size the prop names.
45530
45540
  */
45531
- const css$N = /* css */`
45541
+ const css$O = /* css */`
45532
45542
  @layer navi {
45533
45543
  :root {
45534
45544
  --navi-fixed-bar-width: 56px;
@@ -45676,7 +45686,7 @@ const FixedBar = ({
45676
45686
  border = true,
45677
45687
  ...props
45678
45688
  }) => {
45679
- import.meta.css = [css$N, "@jsenv/navi/src/layout/fixed_bar/fixed_bar.jsx"];
45689
+ import.meta.css = [css$O, "@jsenv/navi/src/layout/fixed_bar/fixed_bar.jsx"];
45680
45690
  const defaultRef = useRef();
45681
45691
  props.ref = props.ref || defaultRef;
45682
45692
  // Said with the width the border rule reads rather than with an attribute of
@@ -45770,7 +45780,7 @@ const FixedBar = ({
45770
45780
  // Subpixel layout rounds rectangles up on boxes that fit exactly.
45771
45781
  const OVERFLOW_TOLERANCE = 1;
45772
45782
 
45773
- const css$M = /* css */ `
45783
+ const css$N = /* css */ `
45774
45784
  [data-navi-overflow-x] {
45775
45785
  outline: 2px dashed #e74c3c;
45776
45786
  outline-offset: -2px;
@@ -45794,7 +45804,7 @@ const detectHorizontalOverflow = ({
45794
45804
  let styleEl = null;
45795
45805
  if (highlight) {
45796
45806
  styleEl = document.createElement("style");
45797
- styleEl.textContent = css$M;
45807
+ styleEl.textContent = css$N;
45798
45808
  document.head.appendChild(styleEl);
45799
45809
  }
45800
45810
 
@@ -45949,7 +45959,7 @@ const useFocusGroup = (
45949
45959
  };
45950
45960
 
45951
45961
  installImportMetaCssBuild(import.meta);const rightArrowPath = "M680-480L360-160l-80-80 240-240-240-240 80-80 320 320z";
45952
- const css$L = /* css */`
45962
+ const css$M = /* css */`
45953
45963
  .navi_summary_marker {
45954
45964
  width: 1em;
45955
45965
  height: 1em;
@@ -46039,7 +46049,7 @@ const SummaryMarker = ({
46039
46049
  loading,
46040
46050
  openDirection = "down"
46041
46051
  }) => {
46042
- import.meta.css = [css$L, "@jsenv/navi/src/control/details/summary_marker.jsx"];
46052
+ import.meta.css = [css$M, "@jsenv/navi/src/control/details/summary_marker.jsx"];
46043
46053
  const showLoading = useDebounceTrue(loading, 300);
46044
46054
  return jsx("span", {
46045
46055
  className: "navi_summary_marker",
@@ -46084,7 +46094,7 @@ const SummaryMarker = ({
46084
46094
  });
46085
46095
  };
46086
46096
 
46087
- installImportMetaCssBuild(import.meta);const css$K = /* css */`
46097
+ installImportMetaCssBuild(import.meta);const css$L = /* css */`
46088
46098
  .navi_details {
46089
46099
  position: relative;
46090
46100
  z-index: 1;
@@ -46130,7 +46140,7 @@ const Details = props => {
46130
46140
  return details;
46131
46141
  };
46132
46142
  const DetailsField = props => {
46133
- import.meta.css = [css$K, "@jsenv/navi/src/control/details/details.jsx"];
46143
+ import.meta.css = [css$L, "@jsenv/navi/src/control/details/details.jsx"];
46134
46144
  const {
46135
46145
  ref,
46136
46146
  persists,
@@ -46350,7 +46360,7 @@ installImportMetaCssBuild(import.meta);/**
46350
46360
  * UI when it comes first). Once settled open the clipping is released, so a
46351
46361
  * popover or focus ring inside is not cut at the edges.
46352
46362
  */
46353
- const css$J = /* css */`
46363
+ const css$K = /* css */`
46354
46364
  .navi_expandable {
46355
46365
  position: relative;
46356
46366
  display: flex;
@@ -46576,7 +46586,7 @@ const useExpandableContext = partName => {
46576
46586
  * and rebuilds it from scratch on every expansion.
46577
46587
  */
46578
46588
  const Expandable = props => {
46579
- import.meta.css = [css$J, "@jsenv/navi/src/control/expandable/expandable.jsx"];
46589
+ import.meta.css = [css$K, "@jsenv/navi/src/control/expandable/expandable.jsx"];
46580
46590
  const {
46581
46591
  ref,
46582
46592
  ui,
@@ -47241,7 +47251,7 @@ const ControlGroup = props => {
47241
47251
  };
47242
47252
  const CONTROL_GROUP_PSEUDO_CLASSES = [":hover", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading"];
47243
47253
 
47244
- installImportMetaCssBuild(import.meta);const css$I = /* css */`
47254
+ installImportMetaCssBuild(import.meta);const css$J = /* css */`
47245
47255
  @layer navi {
47246
47256
  .navi_checkbox {
47247
47257
  --switch-margin: 0; /* Useful to reserve space for outline */
@@ -47319,7 +47329,7 @@ installImportMetaCssBuild(import.meta);const css$I = /* css */`
47319
47329
  }
47320
47330
  `;
47321
47331
  const SwitchUI = () => {
47322
- import.meta.css = [css$I, "@jsenv/navi/src/control/input/switch_ui.jsx"];
47332
+ import.meta.css = [css$J, "@jsenv/navi/src/control/input/switch_ui.jsx"];
47323
47333
  return jsx(Box, {
47324
47334
  className: "navi_switch",
47325
47335
  as: "svg",
@@ -47361,7 +47371,7 @@ const useCheckableProps = (props, options) => {
47361
47371
  return result;
47362
47372
  };
47363
47373
 
47364
- installImportMetaCssBuild(import.meta);const css$H = /* css */`
47374
+ installImportMetaCssBuild(import.meta);const css$I = /* css */`
47365
47375
  @layer navi {
47366
47376
  .navi_checkbox {
47367
47377
  --border-radius: var(--navi-checkbox-border-radius);
@@ -47688,7 +47698,7 @@ const InputCheckboxHeadless = props => {
47688
47698
  });
47689
47699
  };
47690
47700
  const InputCheckboxFieldInterface = props => {
47691
- import.meta.css = [css$H, "@jsenv/navi/src/control/input/input_checkbox.jsx"];
47701
+ import.meta.css = [css$I, "@jsenv/navi/src/control/input/input_checkbox.jsx"];
47692
47702
  const [checkboxRootProps, checkboxHostProps] = useCheckableProps(props);
47693
47703
  const {
47694
47704
  icon,
@@ -47810,7 +47820,7 @@ const CheckboxButtonStyleCSSVars = {
47810
47820
  const CheckboxPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":checked", ":-navi-loading"];
47811
47821
  const CheckboxPseudoElements = ["::-navi-loader", "::-navi-checkmark"];
47812
47822
 
47813
- installImportMetaCssBuild(import.meta);const css$G = /* css */`
47823
+ installImportMetaCssBuild(import.meta);const css$H = /* css */`
47814
47824
  @layer navi {
47815
47825
  .navi_label {
47816
47826
  --label-required-indicator-color: var(--navi-color-danger, #b42318);
@@ -47890,7 +47900,7 @@ installImportMetaCssBuild(import.meta);const css$G = /* css */`
47890
47900
  * </Field>
47891
47901
  */
47892
47902
  const Field = props => {
47893
- import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
47903
+ import.meta.css = [css$H, "@jsenv/navi/src/control/field.jsx"];
47894
47904
  const refDefault = useRef();
47895
47905
  props.ref = props.ref || refDefault;
47896
47906
  const {
@@ -47925,7 +47935,7 @@ const FieldCSSVars = {
47925
47935
  spacingWithControl: "--spacing-with-control"
47926
47936
  };
47927
47937
  const FieldAsContainer = props => {
47928
- import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
47938
+ import.meta.css = [css$H, "@jsenv/navi/src/control/field.jsx"];
47929
47939
  const {
47930
47940
  children
47931
47941
  } = props;
@@ -47957,7 +47967,7 @@ const FieldAsContainer = props => {
47957
47967
  };
47958
47968
  const FIELD_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading"];
47959
47969
  const Label = props => {
47960
- import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
47970
+ import.meta.css = [css$H, "@jsenv/navi/src/control/field.jsx"];
47961
47971
  const {
47962
47972
  children,
47963
47973
  // Marks the label when its control is required. Takes what to show, or
@@ -48119,7 +48129,7 @@ const InputSlot = ({
48119
48129
  });
48120
48130
  };
48121
48131
 
48122
- installImportMetaCssBuild(import.meta);const css$F = /* css */`
48132
+ installImportMetaCssBuild(import.meta);const css$G = /* css */`
48123
48133
  @layer navi {
48124
48134
  .navi_radio {
48125
48135
  --margin: 3px 3px 3px 5px;
@@ -48482,7 +48492,7 @@ const InputRadioHeadless = props => {
48482
48492
  };
48483
48493
  const VARIANT_SET = new Set(["icon", "button", "radio"]);
48484
48494
  const InputRadioFieldInterface = props => {
48485
- import.meta.css = [css$F, "@jsenv/navi/src/control/input/input_radio.jsx"];
48495
+ import.meta.css = [css$G, "@jsenv/navi/src/control/input/input_radio.jsx"];
48486
48496
  const [radioRootProps, radioHostProps] = useCheckableProps(props);
48487
48497
  const {
48488
48498
  icon,
@@ -48628,7 +48638,7 @@ const RadioButtonStyleCSSVars = {
48628
48638
  const RadioPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":checked", ":-navi-loading"];
48629
48639
  const RadioPseudoElements = ["::-navi-loader", "::-navi-radiomark"];
48630
48640
 
48631
- installImportMetaCssBuild(import.meta);const css$E = /* css */`
48641
+ installImportMetaCssBuild(import.meta);const css$F = /* css */`
48632
48642
  @layer navi {
48633
48643
  .navi_input_range {
48634
48644
  --border-radius: 6px;
@@ -48883,7 +48893,7 @@ const InputRange = props => {
48883
48893
  });
48884
48894
  };
48885
48895
  const InputRangeFieldInterface = props => {
48886
- import.meta.css = [css$E, "@jsenv/navi/src/control/input/input_range.jsx"];
48896
+ import.meta.css = [css$F, "@jsenv/navi/src/control/input/input_range.jsx"];
48887
48897
  const {
48888
48898
  ref
48889
48899
  } = props;
@@ -50991,7 +51001,7 @@ installImportMetaCssBuild(import.meta);/**
50991
51001
  * This means an editable thing MUST have a parent with position relative that wraps the content and the eventual editable input
50992
51002
  *
50993
51003
  */
50994
- const css$D = /* css */`
51004
+ const css$E = /* css */`
50995
51005
  .navi_editable_wrapper {
50996
51006
  --inset-top: 0px;
50997
51007
  --inset-right: 0px;
@@ -51040,7 +51050,7 @@ const useEditionController = () => {
51040
51050
  };
51041
51051
  };
51042
51052
  const Editable = props => {
51043
- import.meta.css = [css$D, "@jsenv/navi/src/control/edition/editable.jsx"];
51053
+ import.meta.css = [css$E, "@jsenv/navi/src/control/edition/editable.jsx"];
51044
51054
  let {
51045
51055
  children,
51046
51056
  action,
@@ -51589,7 +51599,7 @@ installImportMetaCssBuild(import.meta);/**
51589
51599
  * meet are drawn once instead of twice, and only the outer corners stay
51590
51600
  * rounded. See docs/control_group.md.
51591
51601
  */
51592
- const css$C = /* css */`
51602
+ const css$D = /* css */`
51593
51603
  .navi_group {
51594
51604
  --group-border-width: var(--navi-control-border-width);
51595
51605
 
@@ -51705,7 +51715,7 @@ const Group = ({
51705
51715
  vertical = row,
51706
51716
  ...props
51707
51717
  }) => {
51708
- import.meta.css = [css$C, "@jsenv/navi/src/control/group.jsx"];
51718
+ import.meta.css = [css$D, "@jsenv/navi/src/control/group.jsx"];
51709
51719
  return jsx(Box, {
51710
51720
  baseClassName: "navi_group",
51711
51721
  "data-vertical": vertical ? "" : undefined
@@ -51871,7 +51881,7 @@ installImportMetaCssBuild(import.meta);/**
51871
51881
  * So: nothing scrollable between the cap and the slides (a shared [data-body]
51872
51882
  * around them IS a scroller, see box.jsx), and `overflow="auto"` on each Slide.
51873
51883
  */
51874
- const css$B = /* css */`
51884
+ const css$C = /* css */`
51875
51885
  /* Where the picture stands relative to the slide that is current, in boxes
51876
51886
  (see paintTravelProgress). Declared, so that it is a NUMBER the browser can
51877
51887
  interpolate: the trait an indicator draws has to travel with the slides,
@@ -52365,7 +52375,7 @@ const SlideContainer = ({
52365
52375
  children,
52366
52376
  ...rest
52367
52377
  }) => {
52368
- import.meta.css = [css$B, "@jsenv/navi/src/layout/slide_container.jsx"];
52378
+ import.meta.css = [css$C, "@jsenv/navi/src/layout/slide_container.jsx"];
52369
52379
  const debugFocus = useDebugFocus();
52370
52380
  const trackRef = useRef();
52371
52381
  // The box itself: it is what takes the keyboard when what is on screen holds
@@ -55210,7 +55220,7 @@ installImportMetaCssBuild(import.meta);/**
55210
55220
  * and only under its own `sizeFromAnchor`) pass through untouched via
55211
55221
  * `...rest` to whichever of Popover/Dialog actually renders.
55212
55222
  */
55213
- const css$A = /* css */`
55223
+ const css$B = /* css */`
55214
55224
  @layer navi {
55215
55225
  .navi_popup {
55216
55226
  --popup-border-radius: var(--navi-popup-border-radius);
@@ -55327,7 +55337,7 @@ const css$A = /* css */`
55327
55337
  * @param {import("ignore:preact").ComponentChildren} props.children
55328
55338
  */
55329
55339
  const Popup = props => {
55330
- import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
55340
+ import.meta.css = [css$B, "@jsenv/navi/src/layout/popup.jsx"];
55331
55341
  const {
55332
55342
  mode: modeProp,
55333
55343
  maxWidth,
@@ -55388,7 +55398,7 @@ const Popup = props => {
55388
55398
  });
55389
55399
  };
55390
55400
 
55391
- installImportMetaCssBuild(import.meta);const css$z = /* css */`
55401
+ installImportMetaCssBuild(import.meta);const css$A = /* css */`
55392
55402
  .navi_picker {
55393
55403
  /* Sizing ceilings (maxmax), background, box-shadow, outline, padding,
55394
55404
  overflow... are already handled correctly by Popup/Popover/Dialog
@@ -55516,7 +55526,7 @@ installImportMetaCssBuild(import.meta);const css$z = /* css */`
55516
55526
  }
55517
55527
  `;
55518
55528
  const PickerCustomResolver = props => {
55519
- import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
55529
+ import.meta.css = [css$A, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
55520
55530
  if (props.children === undefined) {
55521
55531
  return jsx(PickerNative, {
55522
55532
  ...props
@@ -56310,7 +56320,7 @@ const LoadingIndicator = ({
56310
56320
  });
56311
56321
  };
56312
56322
 
56313
- installImportMetaCssBuild(import.meta);const css$y = /* css */`
56323
+ installImportMetaCssBuild(import.meta);const css$z = /* css */`
56314
56324
  @layer navi {
56315
56325
  .navi_separator {
56316
56326
  --size: 1px;
@@ -56388,7 +56398,7 @@ const Separator = ({
56388
56398
  style,
56389
56399
  ...props
56390
56400
  }) => {
56391
- import.meta.css = [css$y, "@jsenv/navi/src/layout/separator.jsx"];
56401
+ import.meta.css = [css$z, "@jsenv/navi/src/layout/separator.jsx"];
56392
56402
  return jsx(Box, {
56393
56403
  as: vertical ? "span" : "hr",
56394
56404
  ...props,
@@ -56881,7 +56891,7 @@ const ListItemFooter = props => {
56881
56891
  });
56882
56892
  };
56883
56893
 
56884
- installImportMetaCssBuild(import.meta);const css$x = /* css */`
56894
+ installImportMetaCssBuild(import.meta);const css$y = /* css */`
56885
56895
  @layer navi {
56886
56896
  .navi_list_container[navi-selectable] {
56887
56897
  /* Focus outline */
@@ -57093,7 +57103,7 @@ const ListSelectableResolver = props => {
57093
57103
  };
57094
57104
  const ListSelectable = props => {
57095
57105
  const Next = useNextResolver();
57096
- import.meta.css = [css$x, "@jsenv/navi/src/control/list/list_selectable.jsx"];
57106
+ import.meta.css = [css$y, "@jsenv/navi/src/control/list/list_selectable.jsx"];
57097
57107
  // we allow ourselves to auto-generate a name
57098
57108
  const defaultName = useId();
57099
57109
  props.name = props.name || `listbox_${defaultName}`;
@@ -57713,7 +57723,7 @@ const ListVirtualContext = createContext(null);
57713
57723
  // that returning a component of one's own — instead of a bare <List.Item> —
57714
57724
  // works the same way.
57715
57725
  const ListRowContext = createContext(null);
57716
- const css$w = /* css */`
57726
+ const css$x = /* css */`
57717
57727
  @layer navi {
57718
57728
  .navi_list_container {
57719
57729
  --list-outline-width: 1px;
@@ -58412,7 +58422,7 @@ const css$w = /* css */`
58412
58422
  }
58413
58423
  `;
58414
58424
  const ListUI = props => {
58415
- import.meta.css = [css$w, "@jsenv/navi/src/control/list/list.jsx"];
58425
+ import.meta.css = [css$x, "@jsenv/navi/src/control/list/list.jsx"];
58416
58426
  const {
58417
58427
  ref,
58418
58428
  renderBudget: renderBudgetProp = RENDER_BUDGET_DEFAULT,
@@ -62081,7 +62091,7 @@ const PickerPresetResolver = props => {
62081
62091
  });
62082
62092
  };
62083
62093
 
62084
- installImportMetaCssBuild(import.meta);const css$v = /* css */`
62094
+ installImportMetaCssBuild(import.meta);const css$w = /* css */`
62085
62095
  @layer navi {
62086
62096
  }
62087
62097
  .navi_badge {
@@ -62193,7 +62203,7 @@ const Badge = ({
62193
62203
  className,
62194
62204
  ...props
62195
62205
  }) => {
62196
- import.meta.css = [css$v, "@jsenv/navi/src/text/badge.jsx"];
62206
+ import.meta.css = [css$w, "@jsenv/navi/src/text/badge.jsx"];
62197
62207
  const defaultRef = useRef();
62198
62208
  props.ref = props.ref || defaultRef;
62199
62209
  const {
@@ -62245,7 +62255,7 @@ const BadgeButton = props => {
62245
62255
  };
62246
62256
  Badge.Button = BadgeButton;
62247
62257
 
62248
- installImportMetaCssBuild(import.meta);const css$u = /* css */`
62258
+ installImportMetaCssBuild(import.meta);const css$v = /* css */`
62249
62259
  @layer navi {
62250
62260
  }
62251
62261
  .navi_badge_list {
@@ -62270,7 +62280,7 @@ const BadgeList = ({
62270
62280
  max,
62271
62281
  ...props
62272
62282
  }) => {
62273
- import.meta.css = [css$u, "@jsenv/navi/src/text/badge_list.jsx"];
62283
+ import.meta.css = [css$v, "@jsenv/navi/src/text/badge_list.jsx"];
62274
62284
  const measureRef = useRef();
62275
62285
  const visibleRef = useRef();
62276
62286
  useLayoutEffect(() => {
@@ -62345,7 +62355,7 @@ const BadgeList = ({
62345
62355
  });
62346
62356
  };
62347
62357
 
62348
- installImportMetaCssBuild(import.meta);const css$t = /* css */`
62358
+ installImportMetaCssBuild(import.meta);const css$u = /* css */`
62349
62359
  .navi_color {
62350
62360
  display: block;
62351
62361
  aspect-ratio: 1/1;
@@ -62376,7 +62386,7 @@ const Color = ({
62376
62386
  children,
62377
62387
  ...rest
62378
62388
  }) => {
62379
- import.meta.css = [css$t, "@jsenv/navi/src/text/color.jsx"];
62389
+ import.meta.css = [css$u, "@jsenv/navi/src/text/color.jsx"];
62380
62390
  const color = children || undefined;
62381
62391
  return jsx(Box, {
62382
62392
  as: "span",
@@ -62833,7 +62843,7 @@ const PickerFileUI = () => {
62833
62843
  return String(value);
62834
62844
  };
62835
62845
 
62836
- installImportMetaCssBuild(import.meta);const css$s = /* css */`
62846
+ installImportMetaCssBuild(import.meta);const css$t = /* css */`
62837
62847
  @layer navi {
62838
62848
  .navi_picker {
62839
62849
  --picker-border-radius: var(--navi-control-border-radius);
@@ -63222,7 +63232,7 @@ installImportMetaCssBuild(import.meta);const css$s = /* css */`
63222
63232
  }
63223
63233
  `;
63224
63234
  const PickerButton = props => {
63225
- import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker.jsx"];
63235
+ import.meta.css = [css$t, "@jsenv/navi/src/control/picker/picker.jsx"];
63226
63236
  if (typeof props.maxLines === "string") {
63227
63237
  props.maxLines = parseInt(props.maxLines);
63228
63238
  }
@@ -63671,7 +63681,7 @@ installImportMetaCssBuild(import.meta);/**
63671
63681
  * refuse it on purpose, which is what keeps the focus where the travel happens
63672
63682
  * instead of moving it into a slide that is about to leave.
63673
63683
  */
63674
- const css$r = /* css */`
63684
+ const css$s = /* css */`
63675
63685
  @layer navi {
63676
63686
  .navi_picker_spin {
63677
63687
  /* A picker one steps through is still a picker: what themes every picker
@@ -64140,7 +64150,7 @@ const Spin = ({
64140
64150
  nextLabel,
64141
64151
  ...rest
64142
64152
  }) => {
64143
- import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64153
+ import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64144
64154
  const id = useId();
64145
64155
  // What the group around it says, when there is one: how big the whole thing
64146
64156
  // is written is said once, on the group, and every spin in it follows.
@@ -64676,7 +64686,7 @@ const renderValueDefault = value => String(value ?? "");
64676
64686
  * are passed on to the spins sitting in them.
64677
64687
  */
64678
64688
  const SpinGroup = props => {
64679
- import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64689
+ import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64680
64690
  const {
64681
64691
  size
64682
64692
  } = props;
@@ -65189,7 +65199,7 @@ const TimeRangeSpin = ({
65189
65199
  };
65190
65200
 
65191
65201
  installImportMetaCssBuild(import.meta);// TOFIX: select in data then reset, it reset to red/blue instead of red/blue/green
65192
- const css$q = /* css */`
65202
+ const css$r = /* css */`
65193
65203
  .navi_checkbox_group {
65194
65204
  border-style: solid;
65195
65205
 
@@ -65230,7 +65240,7 @@ const CheckboxGroup = props => {
65230
65240
  return checkboxGroup;
65231
65241
  };
65232
65242
  const CheckboxGroupInterface = props => {
65233
- import.meta.css = [css$q, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
65243
+ import.meta.css = [css$r, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
65234
65244
  const {
65235
65245
  ref
65236
65246
  } = props;
@@ -65279,7 +65289,7 @@ installImportMetaCssBuild(import.meta);/**
65279
65289
  * shared sheet is registered here too — a page may render a Textarea without
65280
65290
  * any Input.
65281
65291
  */
65282
- const css$p = /* css */`
65292
+ const css$q = /* css */`
65283
65293
  .navi_input.navi_textarea {
65284
65294
  .navi_control_input {
65285
65295
  min-height: calc(var(--textarea-min-rows, 1.5) * 1lh);
@@ -65366,7 +65376,7 @@ const Textarea = ({
65366
65376
  width = "35ch",
65367
65377
  ...props
65368
65378
  }) => {
65369
- import.meta.css = [inputCss + css$p, "@jsenv/navi/src/control/input/textarea.jsx"];
65379
+ import.meta.css = [inputCss + css$q, "@jsenv/navi/src/control/input/textarea.jsx"];
65370
65380
  const defaultRef = useRef(null);
65371
65381
  props.ref = props.ref || defaultRef;
65372
65382
  usePlaceholderHeight(props.ref, props.placeholder);
@@ -65440,7 +65450,7 @@ const TextareaCharCount = ({
65440
65450
  maxLength,
65441
65451
  ...rest
65442
65452
  }) => {
65443
- import.meta.css = [css$p, "@jsenv/navi/src/control/input/textarea.jsx"];
65453
+ import.meta.css = [css$q, "@jsenv/navi/src/control/input/textarea.jsx"];
65444
65454
  const resolvedValue = signal ? signal.value : value;
65445
65455
  const length = typeof resolvedValue === "string" ? resolvedValue.length : 0;
65446
65456
  return jsx(Box, {
@@ -65625,7 +65635,7 @@ const formatIntlUnit = (unit, {
65625
65635
  }
65626
65636
  };
65627
65637
 
65628
- installImportMetaCssBuild(import.meta);const css$o = /* css */`
65638
+ installImportMetaCssBuild(import.meta);const css$p = /* css */`
65629
65639
  .navi_input_duration {
65630
65640
  --duration-separator-spacing: 4px;
65631
65641
  --loader-color: var(--navi-loader-color);
@@ -65692,7 +65702,7 @@ installImportMetaCssBuild(import.meta);const css$o = /* css */`
65692
65702
  * "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
65693
65703
  */
65694
65704
  const InputDuration = props => {
65695
- import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
65705
+ import.meta.css = [css$p, "@jsenv/navi/src/control/input/input_duration.jsx"];
65696
65706
  const defaultRef = useRef();
65697
65707
  props.ref = props.ref || defaultRef;
65698
65708
  props.max = props.max || "23h59";
@@ -66194,7 +66204,7 @@ const InputDurationPart = ({
66194
66204
  });
66195
66205
  };
66196
66206
 
66197
- installImportMetaCssBuild(import.meta);const css$n = /* css */`
66207
+ installImportMetaCssBuild(import.meta);const css$o = /* css */`
66198
66208
  .navi_radio_group {
66199
66209
  border-style: solid;
66200
66210
 
@@ -66214,7 +66224,7 @@ const RadioGroup = props => {
66214
66224
  return radioGroup;
66215
66225
  };
66216
66226
  const RadioGroupInterface = props => {
66217
- import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
66227
+ import.meta.css = [css$o, "@jsenv/navi/src/control/input/radio_group.jsx"];
66218
66228
  const {
66219
66229
  ref
66220
66230
  } = props;
@@ -66272,7 +66282,7 @@ installImportMetaCssBuild(import.meta);/**
66272
66282
  * control is drawn — the list it opens stays the platform's own, which is the
66273
66283
  * whole point of using a select.
66274
66284
  */
66275
- const css$m = /* css */`
66285
+ const css$n = /* css */`
66276
66286
  .navi_input.navi_select {
66277
66287
  .navi_control_input {
66278
66288
  /* Room for the chevron, which sits over the padding rather than beside
@@ -66327,7 +66337,7 @@ const Select = ({
66327
66337
  multiple,
66328
66338
  ...props
66329
66339
  }) => {
66330
- import.meta.css = [inputCss + css$m, "@jsenv/navi/src/control/input/select.jsx"];
66340
+ import.meta.css = [inputCss + css$n, "@jsenv/navi/src/control/input/select.jsx"];
66331
66341
  const defaultRef = useRef(null);
66332
66342
  props.ref = props.ref || defaultRef;
66333
66343
  seedDefaultValueFromSignal(props);
@@ -66395,7 +66405,7 @@ installImportMetaCssBuild(import.meta);/**
66395
66405
  * running: one loading outline around both, which is why each half is told
66396
66406
  * `loadingOutline={false}`.
66397
66407
  */
66398
- const css$l = /* css */`
66408
+ const css$m = /* css */`
66399
66409
  /* Around the pair rather than in it: the outline is drawn against this
66400
66410
  element and follows its corners, and a Group counts its own children to
66401
66411
  know which corners to square — an outline among them would be one of the
@@ -66507,7 +66517,7 @@ const css$l = /* css */`
66507
66517
  * Anything else lands on the split button's own box.
66508
66518
  */
66509
66519
  const SplitButton = props => {
66510
- import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
66520
+ import.meta.css = [css$m, "@jsenv/navi/src/control/input/split_button.jsx"];
66511
66521
  const {
66512
66522
  options = [],
66513
66523
  value,
@@ -67158,7 +67168,7 @@ installImportMetaCssBuild(import.meta);/*
67158
67168
  * accessors (top/height vs left/width) chosen from `horizontal`, and the CSS has
67159
67169
  * a [data-horizontal] variant.
67160
67170
  */
67161
- const css$k = /* css */`
67171
+ const css$l = /* css */`
67162
67172
  .navi_wheel_container {
67163
67173
  /* Row size and emphasis band are read together: the band is what a value
67164
67174
  must cross to lose its emphasis, and the row is how far it has to travel
@@ -68280,7 +68290,7 @@ const useWheelKeyboard = ({
68280
68290
  }, [isHorizontal, interactive, isLoop]);
68281
68291
  };
68282
68292
  function WheelUI(props) {
68283
- import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
68293
+ import.meta.css = [css$l, "@jsenv/navi/src/control/wheel/wheel.jsx"];
68284
68294
  const {
68285
68295
  ref,
68286
68296
  visibleCount = 3,
@@ -69189,7 +69199,7 @@ Wheel.Item = WheelItem;
69189
69199
  * @param {boolean} [props.zoom] - Enlarge the centered value of every wheel (see Wheel's zoom prop) with one prop for the whole group.
69190
69200
  */
69191
69201
  const WheelGroup = props => {
69192
- import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
69202
+ import.meta.css = [css$l, "@jsenv/navi/src/control/wheel/wheel.jsx"];
69193
69203
  // WheelGroup IS a control group: it aggregates its named wheels ("hours",
69194
69204
  // "minutes"…) into one object value, so it can sit directly inside a Form or a
69195
69205
  // Picker with no extra <ControlGroup> wrapper. The wheel-specific presentation
@@ -70054,7 +70064,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
70054
70064
 
70055
70065
  const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
70056
70066
 
70057
- installImportMetaCssBuild(import.meta);const css$j = /* css */`
70067
+ installImportMetaCssBuild(import.meta);const css$k = /* css */`
70058
70068
  .navi_table_drag_clone_container {
70059
70069
  position: absolute;
70060
70070
  top: var(--table-visual-top);
@@ -70209,7 +70219,7 @@ const useTableDragContextValue = ({
70209
70219
  }, [grabTarget, canChangeColumnOrder]);
70210
70220
  };
70211
70221
  const TableDragCloneContainer = forwardRef((props, ref) => {
70212
- import.meta.css = [css$j, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
70222
+ import.meta.css = [css$k, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
70213
70223
  const {
70214
70224
  tableId
70215
70225
  } = props;
@@ -70507,7 +70517,7 @@ installImportMetaCssBuild(import.meta);const ROW_MIN_HEIGHT = 30;
70507
70517
  const ROW_MAX_HEIGHT = 100;
70508
70518
  const COLUMN_MIN_WIDTH = 50;
70509
70519
  const COLUMN_MAX_WIDTH = 500;
70510
- const css$i = /* css */`
70520
+ const css$j = /* css */`
70511
70521
  @layer navi {
70512
70522
  .navi_table {
70513
70523
  --table-resizer-handle-color: #063b7c;
@@ -70667,7 +70677,7 @@ const css$i = /* css */`
70667
70677
 
70668
70678
  // Column resize components
70669
70679
  const TableColumnResizer = props => {
70670
- import.meta.css = [css$i, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
70680
+ import.meta.css = [css$j, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
70671
70681
  const defaultRef = useRef();
70672
70682
  const ref = props.ref || defaultRef;
70673
70683
  return jsxs("div", {
@@ -71138,7 +71148,7 @@ const findPreviousTableRow = currentRow => {
71138
71148
  return currentIndex > 0 ? allRows[currentIndex - 1] : null;
71139
71149
  };
71140
71150
 
71141
- installImportMetaCssBuild(import.meta);const css$h = /* css */`
71151
+ installImportMetaCssBuild(import.meta);const css$i = /* css */`
71142
71152
  @layer navi {
71143
71153
  .navi_table {
71144
71154
  --selection-border-color: var(--navi-selection-border-color, #0078d4);
@@ -71240,7 +71250,7 @@ const useTableSelectionController = ({
71240
71250
  onSelectionChange,
71241
71251
  selectionColor
71242
71252
  }) => {
71243
- import.meta.css = [css$h, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
71253
+ import.meta.css = [css$i, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
71244
71254
  const selectionController = useSelectionController({
71245
71255
  elementRef: tableRef,
71246
71256
  layout: "grid",
@@ -71711,7 +71721,7 @@ const useTableStickyContextValue = ({
71711
71721
  };
71712
71722
 
71713
71723
  installImportMetaCssBuild(import.meta);// TODO: sticky left/top frontier should likely use "followPosition"
71714
- const css$g = /* css */`
71724
+ const css$h = /* css */`
71715
71725
  @layer navi {
71716
71726
  .navi_table {
71717
71727
  --sticky-frontier-color: #c0c0c0;
@@ -71954,7 +71964,7 @@ const css$g = /* css */`
71954
71964
  const TableStickyFrontier = ({
71955
71965
  tableRef
71956
71966
  }) => {
71957
- import.meta.css = [css$g, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
71967
+ import.meta.css = [css$h, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
71958
71968
  const stickyLeftFrontierGhostRef = useRef();
71959
71969
  const stickyLeftFrontierPreviewRef = useRef();
71960
71970
  const stickyTopFrontierGhostRef = useRef();
@@ -72183,7 +72193,7 @@ const initMoveStickyFrontierViaPointer = (pointerdownEvent, {
72183
72193
  * inset 0 -1px 0 0 color; // Bottom border
72184
72194
  */
72185
72195
 
72186
- const css$f = /* css */ `
72196
+ const css$g = /* css */ `
72187
72197
  .navi_table_root {
72188
72198
  position: relative;
72189
72199
  max-width: var(--table-max-width, none);
@@ -72386,7 +72396,7 @@ const css$f = /* css */ `
72386
72396
  }
72387
72397
  `;
72388
72398
 
72389
- installImportMetaCssBuild(import.meta);const css$e = /* css */`
72399
+ installImportMetaCssBuild(import.meta);const css$f = /* css */`
72390
72400
  .navi_table_ui {
72391
72401
  position: fixed;
72392
72402
  inset: 0;
@@ -72397,7 +72407,7 @@ installImportMetaCssBuild(import.meta);const css$e = /* css */`
72397
72407
  }
72398
72408
  `;
72399
72409
  const TableUI = forwardRef((props, ref) => {
72400
- import.meta.css = [css$e, "@jsenv/navi/src/control/table/table_ui.jsx"];
72410
+ import.meta.css = [css$f, "@jsenv/navi/src/control/table/table_ui.jsx"];
72401
72411
  const {
72402
72412
  tableRef,
72403
72413
  tableId,
@@ -72503,7 +72513,7 @@ const RowIndexContext = createContext();
72503
72513
  const TableSectionContext = createContext();
72504
72514
  const useIsInTableHead = () => useContext(TableSectionContext) === "head";
72505
72515
  const Table = props => {
72506
- import.meta.css = [css$f, "@jsenv/navi/src/control/table/table.jsx"];
72516
+ import.meta.css = [css$g, "@jsenv/navi/src/control/table/table.jsx"];
72507
72517
  const tableDefaultRef = useRef();
72508
72518
  const tableDefaultId = `table-${useId()}`;
72509
72519
  const {
@@ -73331,7 +73341,7 @@ const normalizeKey = (key) => {
73331
73341
  return key;
73332
73342
  };
73333
73343
 
73334
- installImportMetaCssBuild(import.meta);const css$d = /* css */`
73344
+ installImportMetaCssBuild(import.meta);const css$e = /* css */`
73335
73345
  .navi_shortcut_container[data-visually-hidden] {
73336
73346
  /* Visually hidden container - doesn't affect layout */
73337
73347
  position: absolute;
@@ -73369,7 +73379,7 @@ installImportMetaCssBuild(import.meta);const css$d = /* css */`
73369
73379
  const ActiveKeyboardShortcuts = ({
73370
73380
  visible
73371
73381
  }) => {
73372
- import.meta.css = [css$d, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
73382
+ import.meta.css = [css$e, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
73373
73383
  const activeShortcuts = activeShortcutsSignal.value;
73374
73384
  return jsx("div", {
73375
73385
  className: "navi_shortcut_container",
@@ -73408,7 +73418,7 @@ const KeyboardShortcutAriaElement = ({
73408
73418
  });
73409
73419
  };
73410
73420
 
73411
- installImportMetaCssBuild(import.meta);const css$c = /* css */`
73421
+ installImportMetaCssBuild(import.meta);const css$d = /* css */`
73412
73422
  @layer navi {
73413
73423
  .navi_clipboard_container {
73414
73424
  --height: 1.5em;
@@ -73440,7 +73450,7 @@ const ButtonCopyToClipboard = ({
73440
73450
  children,
73441
73451
  ...props
73442
73452
  }) => {
73443
- import.meta.css = [css$c, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
73453
+ import.meta.css = [css$d, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
73444
73454
  const [copied, setCopied] = useState(false);
73445
73455
  const renderedRef = useRef();
73446
73456
  useEffect(() => {
@@ -73525,7 +73535,7 @@ const formatNumber = (value, { lang = languagesSignal.value } = {}) => {
73525
73535
  return new Intl.NumberFormat(lang).format(value);
73526
73536
  };
73527
73537
 
73528
- installImportMetaCssBuild(import.meta);const css$b = /* css */`
73538
+ installImportMetaCssBuild(import.meta);const css$c = /* css */`
73529
73539
  @layer navi {
73530
73540
  }
73531
73541
  .navi_text.navi_badge_count {
@@ -73690,7 +73700,7 @@ const BadgeCount = ({
73690
73700
  lineLayout,
73691
73701
  ...props
73692
73702
  }) => {
73693
- import.meta.css = [css$b, "@jsenv/navi/src/text/badge_count.jsx"];
73703
+ import.meta.css = [css$c, "@jsenv/navi/src/text/badge_count.jsx"];
73694
73704
  const defaultRef = useRef();
73695
73705
  props.ref = props.ref || defaultRef;
73696
73706
  const {
@@ -73832,7 +73842,7 @@ const BadgeCountCircle = ({
73832
73842
  });
73833
73843
  };
73834
73844
 
73835
- installImportMetaCssBuild(import.meta);const css$a = /* css */`
73845
+ installImportMetaCssBuild(import.meta);const css$b = /* css */`
73836
73846
  @layer navi {
73837
73847
  .navi_caption {
73838
73848
  --color: #6b7280;
@@ -73853,7 +73863,7 @@ const Caption = ({
73853
73863
  className,
73854
73864
  ...rest
73855
73865
  }) => {
73856
- import.meta.css = [css$a, "@jsenv/navi/src/text/caption.jsx"];
73866
+ import.meta.css = [css$b, "@jsenv/navi/src/text/caption.jsx"];
73857
73867
  return jsx(Text, {
73858
73868
  as: "small",
73859
73869
  size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
@@ -74266,7 +74276,7 @@ const WarningSvg = () => {
74266
74276
  });
74267
74277
  };
74268
74278
 
74269
- installImportMetaCssBuild(import.meta);const css$9 = /* css */`
74279
+ installImportMetaCssBuild(import.meta);const css$a = /* css */`
74270
74280
  @layer navi {
74271
74281
  .navi_message_box {
74272
74282
  --background-color-info: var(--navi-info-color-light);
@@ -74323,7 +74333,7 @@ const MessageBox = ({
74323
74333
  onClose,
74324
74334
  ...rest
74325
74335
  }) => {
74326
- import.meta.css = [css$9, "@jsenv/navi/src/text/message_box.jsx"];
74336
+ import.meta.css = [css$a, "@jsenv/navi/src/text/message_box.jsx"];
74327
74337
  const [hasTitleChild, setHasTitleChild] = useState(false);
74328
74338
  const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
74329
74339
  if (icon === true) {
@@ -74386,7 +74396,7 @@ const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success",
74386
74396
  const MessageBoxStatusContext = createContext();
74387
74397
  const MessageBoxReportTitleChildContext = createContext();
74388
74398
 
74389
- installImportMetaCssBuild(import.meta);const css$8 = /* css */`
74399
+ installImportMetaCssBuild(import.meta);const css$9 = /* css */`
74390
74400
  @layer navi {
74391
74401
  }
74392
74402
 
@@ -74477,7 +74487,7 @@ const Quantity = ({
74477
74487
  bold = true,
74478
74488
  ...props
74479
74489
  }) => {
74480
- import.meta.css = [css$8, "@jsenv/navi/src/text/quantity.jsx"];
74490
+ import.meta.css = [css$9, "@jsenv/navi/src/text/quantity.jsx"];
74481
74491
  const value = parseQuantityValue(children);
74482
74492
  const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
74483
74493
  const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
@@ -74535,7 +74545,7 @@ const parseQuantityValue = children => {
74535
74545
  return Number.isNaN(parsed) ? children : parsed;
74536
74546
  };
74537
74547
 
74538
- installImportMetaCssBuild(import.meta);const css$7 = /* css */`
74548
+ installImportMetaCssBuild(import.meta);const css$8 = /* css */`
74539
74549
  @layer navi {
74540
74550
  .navi_meter {
74541
74551
  --loader-color: var(--navi-loader-color);
@@ -74673,7 +74683,7 @@ const Meter = ({
74673
74683
  style,
74674
74684
  ...rest
74675
74685
  }) => {
74676
- import.meta.css = [css$7, "@jsenv/navi/src/text/meter.jsx"];
74686
+ import.meta.css = [css$8, "@jsenv/navi/src/text/meter.jsx"];
74677
74687
  const defaultRef = useRef();
74678
74688
  const ref = rest.ref || defaultRef;
74679
74689
  value = Number(value);
@@ -74798,7 +74808,7 @@ const Paragraph = props => {
74798
74808
  });
74799
74809
  };
74800
74810
 
74801
- installImportMetaCssBuild(import.meta);const css$6 = /* css */`
74811
+ installImportMetaCssBuild(import.meta);const css$7 = /* css */`
74802
74812
  .navi_text_box {
74803
74813
  min-width: 0;
74804
74814
  align-items: flex-start;
@@ -74840,7 +74850,7 @@ const TextBox = ({
74840
74850
  children,
74841
74851
  ...rest
74842
74852
  }) => {
74843
- import.meta.css = [css$6, "@jsenv/navi/src/text/text_box.jsx"];
74853
+ import.meta.css = [css$7, "@jsenv/navi/src/text/text_box.jsx"];
74844
74854
  const boxRef = useRef(null);
74845
74855
  const contentRef = useRef(null);
74846
74856
  useLayoutEffect(() => {
@@ -74886,7 +74896,7 @@ const adjustWidth = (boxEl, contentEl) => {
74886
74896
  contentEl.style.width = `${Math.ceil(optimalWidth)}px`;
74887
74897
  };
74888
74898
 
74889
- installImportMetaCssBuild(import.meta);const css$5 = /* css */`
74899
+ installImportMetaCssBuild(import.meta);const css$6 = /* css */`
74890
74900
  .navi_message_box {
74891
74901
  .navi_title {
74892
74902
  margin-top: 0;
@@ -74896,7 +74906,7 @@ installImportMetaCssBuild(import.meta);const css$5 = /* css */`
74896
74906
  }
74897
74907
  `;
74898
74908
  const Title = props => {
74899
- import.meta.css = [css$5, "@jsenv/navi/src/text/title.jsx"];
74909
+ import.meta.css = [css$6, "@jsenv/navi/src/text/title.jsx"];
74900
74910
  const messageBoxStatus = useContext(MessageBoxStatusContext);
74901
74911
  const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
74902
74912
  const titleLevel = parseInt(innerAs.slice(1));
@@ -74920,7 +74930,7 @@ const useTitleLevel = () => {
74920
74930
  };
74921
74931
  const TitlePseudoClasses = [":hover"];
74922
74932
 
74923
- installImportMetaCssBuild(import.meta);const css$4 = /* css */`
74933
+ installImportMetaCssBuild(import.meta);const css$5 = /* css */`
74924
74934
  @keyframes navi_image_shimmer {
74925
74935
  0% {
74926
74936
  background-position: -200% 0;
@@ -74975,7 +74985,7 @@ const Image = ({
74975
74985
  placeholderDark = false,
74976
74986
  ...rest
74977
74987
  }) => {
74978
- import.meta.css = [css$4, "@jsenv/navi/src/graphic/image.jsx"];
74988
+ import.meta.css = [css$5, "@jsenv/navi/src/graphic/image.jsx"];
74979
74989
  const loadedRef = useRef();
74980
74990
  let resolvedPlaceholder = placeholderColor;
74981
74991
  if (resolvedPlaceholder === undefined) {
@@ -75041,7 +75051,7 @@ installImportMetaCssBuild(import.meta);/**
75041
75051
  * @param {ReactNode[]} props.children - SVG elements (first is base, rest are overlays)
75042
75052
  * @returns {ReactElement} A composed SVG with all elements properly masked
75043
75053
  */
75044
- const css$3 = /* css */`
75054
+ const css$4 = /* css */`
75045
75055
  .svg_mask_content * {
75046
75056
  color: black !important;
75047
75057
  opacity: 1 !important;
@@ -75055,7 +75065,7 @@ const SVGMaskOverlay = ({
75055
75065
  viewBox,
75056
75066
  children
75057
75067
  }) => {
75058
- import.meta.css = [css$3, "@jsenv/navi/src/graphic/svg_mask_overlay.jsx"];
75068
+ import.meta.css = [css$4, "@jsenv/navi/src/graphic/svg_mask_overlay.jsx"];
75059
75069
  if (!Array.isArray(children)) {
75060
75070
  return children;
75061
75071
  }
@@ -75119,7 +75129,7 @@ installImportMetaCssBuild(import.meta);/**
75119
75129
  * space the outer box genuinely occupies — so a narrow window shrinks the card
75120
75130
  * and still shows that room, instead of pushing it against the edges.
75121
75131
  */
75122
- const css$2 = /* css */`
75132
+ const css$3 = /* css */`
75123
75133
  @layer navi {
75124
75134
  .navi_card_layout {
75125
75135
  --layout-margin: 30px;
@@ -75225,7 +75235,7 @@ const CardLayout = ({
75225
75235
  alignY = "center",
75226
75236
  ...props
75227
75237
  }) => {
75228
- import.meta.css = [css$2, "@jsenv/navi/src/layout/card_layout.jsx"];
75238
+ import.meta.css = [css$3, "@jsenv/navi/src/layout/card_layout.jsx"];
75229
75239
  return jsx(Box, {
75230
75240
  baseClassName: "navi_card_layout",
75231
75241
  styleCSSVars: CardLayoutStyleCSSVars,
@@ -75241,6 +75251,565 @@ const CardLayout = ({
75241
75251
  });
75242
75252
  };
75243
75253
 
75254
+ installImportMetaCssBuild(import.meta);/**
75255
+ * Where one stands in a walk of steps, drawn as dots on a path.
75256
+ *
75257
+ * Two distinct facts, drawn separately — they usually agree, and everything
75258
+ * this component says comes from the moments they do not:
75259
+ *
75260
+ * - the PATH (`reached`): how far the steps are answered without a gap. A
75261
+ * solid line runs from the first dot to the step it names, and those dots
75262
+ * are filled; past it the line is dashed — the road not walked yet. It
75263
+ * moves when a step is answered, not when one merely looks around.
75264
+ * - the POSITION (`current`): the step being looked at, marked by a halo
75265
+ * around its dot and its label emphasized. It travels freely, so it can be
75266
+ * AHEAD of the path (browsing step 3 while step 1 still misses an answer)
75267
+ * or BEHIND it (back on step 1 to change something already answered).
75268
+ *
75269
+ * Both move smoothly on change (a CSS transition each), so pressing a step
75270
+ * or answering one is seen travelling rather than jumping.
75271
+ *
75272
+ * The dots are drawn in SVG, twice: a muted layer, and a filled layer
75273
+ * clipped at the path's edge — the clip is what makes the path's progress a
75274
+ * single sweep that fills the line and the dots it crosses in one movement.
75275
+ * The line is drawn as segments between the dots (never behind them), so the
75276
+ * dots need no background of their own and the component sits on any
75277
+ * surface. Colors are CSS custom properties (see the css below), overridden
75278
+ * from outside for a dark band or a different accent.
75279
+ *
75280
+ * The steps are the CHILDREN — <StepList.Item value="club">Club</StepList.Item>
75281
+ * — read off the vnodes (toChildArray, so a .map() or a fragment is fine; a
75282
+ * component of your own wrapping an Item is not seen). The Item renders its
75283
+ * label; everything positional is this component's business.
75284
+ *
75285
+ * `slideContainer` connects the list to a <SlideContainer> by id, both ways:
75286
+ * pressing a step travels there (--navi-go-to-slide), and the position is
75287
+ * READ off the container rather than said by a prop — including mid-travel:
75288
+ * the container paints --slide-travel-progress on this element (it is a
75289
+ * follower, same mechanism as <Nav slideContainer>), so the halo rides the
75290
+ * drag under the finger, in CSS alone. The path then follows the position
75291
+ * too, clamped between `reached` (never retracts) and `reachable` (never
75292
+ * ahead of the answers): dragging towards a step whose way is earned fills
75293
+ * the line under the finger, dragging past the answers does not.
75294
+ */
75295
+ const css$2 = /* css */`
75296
+ .navi_step_list {
75297
+ /* The knobs: accent is the path, muted is what the path has not
75298
+ reached, on-accent writes on filled dots, and --step-list-path-line
75299
+ exists apart from the accent for a dark band where the walked line
75300
+ reads better plain white. Said from OUTSIDE (any ancestor — a dark
75301
+ band, a themed app) on the plain names; resolved here through an
75302
+ indirection (--x-…, the way Button does), because a default written
75303
+ on the plain name on this very element would beat anything an
75304
+ ancestor says. */
75305
+ --x-step-list-accent: var(--step-list-accent, #4f8ef7);
75306
+ --x-step-list-on-accent: var(--step-list-on-accent, white);
75307
+ --x-step-list-muted: var(--step-list-muted, light-dark(#8a93a8, #8b99b8));
75308
+ --x-step-list-line: var(
75309
+ --step-list-line,
75310
+ light-dark(#c9d0dd, rgba(255, 255, 255, 0.35))
75311
+ );
75312
+ --x-step-list-current-color: var(
75313
+ --step-list-current-color,
75314
+ light-dark(#1c2433, white)
75315
+ );
75316
+ --x-step-list-path-line: var(
75317
+ --step-list-path-line,
75318
+ var(--x-step-list-accent)
75319
+ );
75320
+
75321
+ position: relative;
75322
+ display: block;
75323
+ height: 64px;
75324
+ }
75325
+ .navi_step_list_rail {
75326
+ position: absolute;
75327
+ top: 0;
75328
+ left: 0;
75329
+ pointer-events: none;
75330
+ }
75331
+ /* The road not walked yet. */
75332
+ .navi_step_list_rail line {
75333
+ stroke: var(--x-step-list-line);
75334
+ stroke-width: 2;
75335
+ stroke-dasharray: 4 5;
75336
+ }
75337
+ .navi_step_list_rail circle {
75338
+ fill: none;
75339
+ stroke: var(--x-step-list-muted);
75340
+ stroke-width: 1.5;
75341
+ }
75342
+ .navi_step_list_rail text {
75343
+ font-weight: 600;
75344
+ font-size: 12px;
75345
+ fill: var(--x-step-list-muted);
75346
+ }
75347
+ /* The current dot says so in the drawing itself, not only by its halo: on
75348
+ a dark band a muted number under a faint ring reads as nothing. Said in
75349
+ the base layer only (see renderRail) — a current dot the path has
75350
+ covered keeps the filled colors. */
75351
+ .navi_step_list_rail g[data-current] circle {
75352
+ stroke: var(--x-step-list-current-color);
75353
+ }
75354
+ .navi_step_list_rail g[data-current] text {
75355
+ fill: var(--x-step-list-current-color);
75356
+ }
75357
+ /* The path: same drawing, filled, revealed up to the step it has come to.
75358
+ The clip is set inline (a width in px); transitioning it is what makes
75359
+ an answered step SWEEP the line and the next dot rather than pop. */
75360
+ .navi_step_list_rail_filled {
75361
+ transition: clip-path 300ms ease;
75362
+ }
75363
+ .navi_step_list_rail_filled line {
75364
+ stroke: var(--x-step-list-path-line);
75365
+ stroke-dasharray: none;
75366
+ }
75367
+ .navi_step_list_rail_filled circle {
75368
+ fill: var(--x-step-list-accent);
75369
+ stroke: var(--x-step-list-accent);
75370
+ }
75371
+ .navi_step_list_rail_filled text {
75372
+ fill: var(--x-step-list-on-accent);
75373
+ }
75374
+ /* The position: a halo around the dot being looked at. It slides from dot
75375
+ to dot (transform, transitioned) — the g moves, the circle inside is
75376
+ drawn at x=0. */
75377
+ .navi_step_list_marker {
75378
+ transition: transform 300ms ease;
75379
+ }
75380
+ .navi_step_list_marker circle {
75381
+ fill: none;
75382
+ stroke: color-mix(in srgb, var(--x-step-list-accent) 65%, transparent);
75383
+ stroke-width: 1.5;
75384
+ }
75385
+
75386
+ /* Connected to slides: the movement is not this component's anymore. The
75387
+ container paints --slide-travel-progress here (this element follows it,
75388
+ see data-slide-container-follows) — an asked-for travel animates it, a
75389
+ finger drags it — and everything below is a calc() of that number, so
75390
+ the halo and the path move per frame in CSS alone. The transitions are
75391
+ off: they would chase a finger that is already the pace.
75392
+ Position, in dots-x px: where the picture is right now. */
75393
+ .navi_step_list[data-slide-container-follows] {
75394
+ --step-list-position: calc(
75395
+ var(--step-list-pos-x, 0) + var(--slide-travel-progress) *
75396
+ var(--step-list-pos-dx, 0)
75397
+ );
75398
+ }
75399
+ .navi_step_list[data-slide-container-follows] .navi_step_list_marker {
75400
+ transform: translateX(calc(var(--step-list-position) * 1px));
75401
+ transition: none;
75402
+ }
75403
+ /* The path follows the position, clamped: never back below what was
75404
+ earned (--step-list-reached-x), never ahead of what the answers allow
75405
+ (--step-list-reachable-x). The +14 covers the dot it stands on (radius
75406
+ plus stroke). */
75407
+ .navi_step_list[data-slide-container-follows] .navi_step_list_rail_filled {
75408
+ clip-path: inset(
75409
+ 0
75410
+ calc(
75411
+ (
75412
+ var(--step-list-w, 0) -
75413
+ (
75414
+ clamp(
75415
+ var(--step-list-reached-x, -9999),
75416
+ var(--step-list-position),
75417
+ var(--step-list-reachable-x, -9999)
75418
+ ) +
75419
+ 14
75420
+ )
75421
+ ) *
75422
+ 1px
75423
+ )
75424
+ 0 0
75425
+ );
75426
+ transition: none;
75427
+ }
75428
+
75429
+ /* One press target per step, covering the dot AND the label under it. The
75430
+ feedback is NOT the whole surface: a rectangle would say the whole band
75431
+ is a button, when the affordance is the dot — so hover and focus land on
75432
+ a circle drawn over the dot (::before), plus the label brightening.
75433
+ --step-dot-x anchors both on the dot, wherever the dot sits in the slot:
75434
+ the first and last slots are asymmetric (cut at the container's edge,
75435
+ see the geometry in the component). */
75436
+ .navi_step_list_slot {
75437
+ position: absolute;
75438
+ top: 0;
75439
+ box-sizing: border-box;
75440
+ height: 100%;
75441
+ }
75442
+ /* Doubled selector: the button's own state formulas (a readonly color
75443
+ mixed at the variant level) are declared in navi's stylesheet, injected
75444
+ after this one — specificity is what makes these values the ones read. */
75445
+ .navi_step_list .navi_step_list_step {
75446
+ position: relative;
75447
+ display: block;
75448
+ width: 100%;
75449
+ height: 100%;
75450
+ padding: 0;
75451
+ font-size: 12px;
75452
+ outline: none;
75453
+ --button-color: var(--x-step-list-muted);
75454
+ --button-color-readonly: var(--x-step-list-muted);
75455
+ /* The button's own focus ring, silenced: it would outline the whole
75456
+ press surface, and the ring this list draws is the one around the dot
75457
+ (see the ::before rules below) — two rings read as a mistake. Width
75458
+ rather than style, because the ::before sets its own style in full. */
75459
+ --button-outline-width: 0px;
75460
+ }
75461
+ /* Centered on the dot: same vertical middle as the rail (top 0, height 34,
75462
+ cy 17). */
75463
+ .navi_step_list_step::before {
75464
+ position: absolute;
75465
+ top: 17px;
75466
+ left: var(--step-dot-x);
75467
+ width: 30px;
75468
+ height: 30px;
75469
+ border-radius: 50%;
75470
+ translate: -50% -50%;
75471
+ content: "";
75472
+ }
75473
+ .navi_step_list_step:hover::before,
75474
+ .navi_step_list_step[data-hover]::before {
75475
+ background: color-mix(in srgb, var(--x-step-list-accent) 15%, transparent);
75476
+ }
75477
+ .navi_step_list .navi_step_list_step:hover,
75478
+ .navi_step_list .navi_step_list_step[data-hover] {
75479
+ --button-color: var(--x-step-list-current-color);
75480
+ }
75481
+ .navi_step_list_step:focus-visible::before,
75482
+ .navi_step_list_step[data-focus-visible]::before {
75483
+ outline-width: var(--navi-focus-outline-width);
75484
+ outline-style: solid;
75485
+ outline-color: var(--navi-focus-outline-color);
75486
+ outline-offset: 1px;
75487
+ }
75488
+ .navi_step_list_label {
75489
+ position: absolute;
75490
+ bottom: 6px;
75491
+ left: var(--step-dot-x);
75492
+ white-space: nowrap;
75493
+ translate: -50% 0;
75494
+ }
75495
+ .navi_step_list .navi_step_list_step[data-current] {
75496
+ font-weight: 600;
75497
+ --button-color: var(--x-step-list-current-color);
75498
+ --button-color-readonly: var(--x-step-list-current-color);
75499
+ }
75500
+ `;
75501
+ const RAIL_H = 34;
75502
+ const DOT_R = 11;
75503
+ const RING_R = 14.5;
75504
+ // Room for the first and last dot (and their halo) not to touch the edges.
75505
+ const EDGE_INSET = 30;
75506
+ // Between a dot's edge and the line running to the next one: enough for the
75507
+ // halo of a current dot not to sit on the line.
75508
+ const LINE_GAP = 5;
75509
+
75510
+ /**
75511
+ * @type {import("ignore:preact").FunctionComponent<{
75512
+ * current?: string,
75513
+ * reached?: string,
75514
+ * reachable?: string,
75515
+ * slideContainer?: string,
75516
+ * travelByClick?: boolean,
75517
+ * travelByKeyboard?: boolean,
75518
+ * [key: string]: any,
75519
+ * }>}
75520
+ * @param {string} [current] - the step being looked at: its dot gets the
75521
+ * halo, its label the emphasis. Omit for "nowhere" — a confirmation
75522
+ * screen after the walk, say. With `slideContainer` the position is read
75523
+ * off the container instead, and this prop is ignored.
75524
+ * @param {string} [reached] - the step the path has come to: the line is
75525
+ * solid and the dots filled up to it, dashed past it. Omit for a path
75526
+ * that has not started.
75527
+ * @param {string} [reachable] - how far the path MAY go (with
75528
+ * `slideContainer` only): between `reached` and this step the path
75529
+ * follows the position — a drag towards a step whose way is earned fills
75530
+ * the line under the finger. Defaults to `reached`: the path then never
75531
+ * moves with the position at all.
75532
+ * @param {string} [slideContainer] - id of a <SlideContainer> these steps
75533
+ * are the slides of. Pressing a step travels there
75534
+ * (--navi-go-to-slide), the halo follows the container — drags included —
75535
+ * and this element becomes a follower of the container
75536
+ * (data-slide-container-follows), which is also what keeps the arrow keys
75537
+ * working from here.
75538
+ * @param {boolean} [travelByClick=true] - whether pressing a step goes
75539
+ * there. Off, the steps are read-only — shown, not offered. To DO
75540
+ * something on a press, say `onClick` on the Item itself: like every other
75541
+ * prop an Item carries, it lands on that step's button.
75542
+ * @param {boolean} [travelByKeyboard=true] - whether the arrow keys walk
75543
+ * from one step to the other (the focus moves, Enter presses). Only when
75544
+ * the list stands alone: connected to slides the arrows belong to the
75545
+ * CONTAINER — this element is a follower, so a press here already walks
75546
+ * the slides, and the container's own `travelByKeyboard` is the one that
75547
+ * says so. One owner per mode, or one arrow would do both.
75548
+ */
75549
+ const StepList = ({
75550
+ current,
75551
+ reached,
75552
+ reachable,
75553
+ slideContainer,
75554
+ travelByClick = true,
75555
+ travelByKeyboard = true,
75556
+ children,
75557
+ ...rest
75558
+ }) => {
75559
+ import.meta.css = [css$2, "@jsenv/navi/src/layout/step_list.jsx"];
75560
+ const rootRef = useRef();
75561
+ // The dots spread over whatever width the component is given, so the
75562
+ // geometry is measured rather than declared — and measured again when the
75563
+ // room changes.
75564
+ const [width, setWidth] = useState(0);
75565
+ useLayoutEffect(() => {
75566
+ const rootElement = rootRef.current;
75567
+ const measure = () => {
75568
+ setWidth(rootElement.clientWidth);
75569
+ };
75570
+ measure();
75571
+ const observer = new ResizeObserver(measure);
75572
+ observer.observe(rootElement);
75573
+ return () => {
75574
+ observer.disconnect();
75575
+ };
75576
+ }, []);
75577
+
75578
+ // The arrows walk the steps — standing alone only: connected, this element
75579
+ // follows the container, whose own keydown listener already walks the
75580
+ // slides from here (and whose travelByKeyboard says whether to). A focus
75581
+ // group on top of that would make one arrow do both.
75582
+ useFocusGroup(rootRef, {
75583
+ enabled: Boolean(travelByKeyboard) && !slideContainer,
75584
+ direction: "x"
75585
+ });
75586
+
75587
+ // The steps, read off the children: each <StepList.Item> vnode says which
75588
+ // step it is (value) and is rendered as the label under its dot.
75589
+ const stepVNodes = toChildArray(children).filter(child => child && child.props);
75590
+ const stepCount = stepVNodes.length;
75591
+ const valueOf = (vnode, index) => vnode.props.value ?? String(index);
75592
+ const dotXs = [];
75593
+ if (width > 0 && stepCount > 0) {
75594
+ const span = width - EDGE_INSET * 2;
75595
+ let index = 0;
75596
+ while (index < stepCount) {
75597
+ dotXs.push(stepCount === 1 ? width / 2 : EDGE_INSET + span * index / (stepCount - 1));
75598
+ index++;
75599
+ }
75600
+ }
75601
+ const indexOf = value => stepVNodes.findIndex((vnode, index) => valueOf(vnode, index) === value);
75602
+
75603
+ // Where the slides are, read off the container: which slide is current,
75604
+ // and — while a travel or a drag is playing — which one the picture leans
75605
+ // towards. The current area re-renders this component (the emphasized
75606
+ // label, the data-current dot); the in-between positions never do: they
75607
+ // are written as numbers on this element and interpolated by the CSS
75608
+ // above, at the pace of --slide-travel-progress.
75609
+ const [containerCurrent, setContainerCurrent] = useState(undefined);
75610
+ useLayoutEffect(() => {
75611
+ if (!slideContainer || dotXs.length === 0) {
75612
+ return undefined;
75613
+ }
75614
+ const containerElement = document.getElementById(slideContainer);
75615
+ if (!containerElement) {
75616
+ console.warn(`<StepList slideContainer="${slideContainer}"> but no element with that id found`);
75617
+ return undefined;
75618
+ }
75619
+ const rootElement = rootRef.current;
75620
+ const read = () => {
75621
+ const currentArea = containerElement.getAttribute("data-slide-current");
75622
+ const towardArea = containerElement.getAttribute("data-slide-travel-toward");
75623
+ setContainerCurrent(currentArea ?? undefined);
75624
+ const currentIdx = currentArea === null ? -1 : indexOf(currentArea);
75625
+ if (currentIdx === -1) {
75626
+ // A slide no step names (a confirmation screen): the halo is not
75627
+ // rendered, and the last position is left standing for the path.
75628
+ return;
75629
+ }
75630
+ const x = dotXs[currentIdx];
75631
+ let dx = 0;
75632
+ if (towardArea && towardArea !== currentArea) {
75633
+ const towardIdx = indexOf(towardArea);
75634
+ if (towardIdx !== -1 && towardIdx !== currentIdx) {
75635
+ // The container counts +1 when the picture leans on a slide BEFORE
75636
+ // the current one, -1 after: the delta is signed the same way, so
75637
+ // progress × delta lands exactly on the other dot.
75638
+ const sign = towardIdx > currentIdx ? -1 : 1;
75639
+ dx = (dotXs[towardIdx] - x) * sign;
75640
+ }
75641
+ }
75642
+ rootElement.style.setProperty("--step-list-pos-x", x);
75643
+ rootElement.style.setProperty("--step-list-pos-dx", dx);
75644
+ };
75645
+ read();
75646
+ const observer = new MutationObserver(read);
75647
+ observer.observe(containerElement, {
75648
+ attributes: true,
75649
+ attributeFilter: ["data-slide-current", "data-slide-travel-toward"]
75650
+ });
75651
+ return () => {
75652
+ observer.disconnect();
75653
+ };
75654
+ // width: the dots move when the room does, and the written positions are
75655
+ // pixels of those dots.
75656
+ }, [slideContainer, width, stepCount]);
75657
+ const resolvedCurrent = slideContainer ? containerCurrent : current;
75658
+ const currentIndex = resolvedCurrent === undefined ? -1 : indexOf(resolvedCurrent);
75659
+ const reachedIndex = reached === undefined ? -1 : indexOf(reached);
75660
+ let reachableIndex = reachable === undefined ? -1 : indexOf(reachable);
75661
+ if (reachableIndex < reachedIndex) {
75662
+ reachableIndex = reachedIndex;
75663
+ }
75664
+ // Covers the reached dot entirely (radius plus stroke), and nothing when
75665
+ // the path has not started.
75666
+ const fillX = reachedIndex === -1 ? 0 : dotXs[reachedIndex] + DOT_R + 3;
75667
+ const cy = RAIL_H / 2;
75668
+ const slotWidth = dotXs.length > 1 ? dotXs[1] - dotXs[0] : width;
75669
+ const renderRail = filled => jsx("svg", {
75670
+ className: filled ? "navi_step_list_rail navi_step_list_rail_filled" : "navi_step_list_rail",
75671
+ style: filled && !slideContainer ? {
75672
+ clipPath: `inset(0 ${width - fillX}px 0 0)`
75673
+ } : undefined,
75674
+ width: width,
75675
+ height: RAIL_H,
75676
+ viewBox: `0 0 ${width} ${RAIL_H}`,
75677
+ "aria-hidden": "true",
75678
+ children: dotXs.map((x, index) => jsxs("g", {
75679
+ // Base layer only: a current dot the path covers keeps the filled
75680
+ // colors (see the css).
75681
+ "data-current": !filled && index === currentIndex ? "" : undefined,
75682
+ children: [index > 0 ? jsx("line", {
75683
+ x1: dotXs[index - 1] + DOT_R + LINE_GAP,
75684
+ y1: cy,
75685
+ x2: x - DOT_R - LINE_GAP,
75686
+ y2: cy
75687
+ }) : null, jsx("circle", {
75688
+ cx: x,
75689
+ cy: cy,
75690
+ r: DOT_R
75691
+ }), jsx("text", {
75692
+ x: x,
75693
+ y: cy,
75694
+ dy: "0.36em",
75695
+ "text-anchor": "middle",
75696
+ children: index + 1
75697
+ })]
75698
+ }, valueOf(stepVNodes[index], index)))
75699
+ });
75700
+ return jsx(Box, {
75701
+ ...rest,
75702
+ ref: rootRef,
75703
+ baseClassName: "navi_step_list",
75704
+ "data-step-list": ""
75705
+ // A follower of the container: the travel's progress is painted here
75706
+ // for the CSS to draw with, and the arrow keys keep walking the slides
75707
+ // from this element.
75708
+ ,
75709
+
75710
+ "data-slide-container-follows": slideContainer,
75711
+ style: {
75712
+ ...rest.style,
75713
+ ...(slideContainer ? {
75714
+ "--step-list-w": width,
75715
+ "--step-list-reached-x": reachedIndex === -1 ? -9999 : dotXs[reachedIndex],
75716
+ "--step-list-reachable-x": reachableIndex === -1 ? -9999 : dotXs[reachableIndex]
75717
+ } : undefined)
75718
+ },
75719
+ children: width > 0 && stepCount > 0 ? jsxs(Fragment$1, {
75720
+ children: [renderRail(false), renderRail(true), currentIndex !== -1 && dotXs[currentIndex] !== undefined ? jsx("svg", {
75721
+ className: "navi_step_list_rail",
75722
+ width: width,
75723
+ height: RAIL_H,
75724
+ viewBox: `0 0 ${width} ${RAIL_H}`,
75725
+ "aria-hidden": "true",
75726
+ children: jsx("g", {
75727
+ className: "navi_step_list_marker"
75728
+ // Connected to slides, the position comes from the CSS calc
75729
+ // above — an inline transform would override it.
75730
+ ,
75731
+
75732
+ style: slideContainer ? undefined : {
75733
+ transform: `translateX(${dotXs[currentIndex]}px)`
75734
+ },
75735
+ children: jsx("circle", {
75736
+ cx: "0",
75737
+ cy: cy,
75738
+ r: RING_R
75739
+ })
75740
+ })
75741
+ }) : null, stepVNodes.map((stepVNode, index) => {
75742
+ const value = valueOf(stepVNode, index);
75743
+ // Whatever else the Item was given reaches its button — a
75744
+ // pseudoState held for a demo, an aria attribute.
75745
+ const itemRest = {
75746
+ ...stepVNode.props
75747
+ };
75748
+ delete itemRest.value;
75749
+ delete itemRest.children;
75750
+ // The slots tile the row, cut at the container's edges: the
75751
+ // first and the last cover only the inner half of the room an
75752
+ // interior slot gets, so pressing just outside the box presses
75753
+ // nothing.
75754
+ const first = index === 0;
75755
+ const last = index === stepCount - 1;
75756
+ const slotLeft = first ? dotXs[index] - EDGE_INSET : dotXs[index] - slotWidth / 2;
75757
+ const slotRight = last ? dotXs[index] + EDGE_INSET : dotXs[index] + slotWidth / 2;
75758
+ return jsx("div", {
75759
+ className: "navi_step_list_slot",
75760
+ style: {
75761
+ "left": `${slotLeft}px`,
75762
+ "width": `${slotRight - slotLeft}px`,
75763
+ "--step-dot-x": `${dotXs[index] - slotLeft}px`
75764
+ },
75765
+ children: jsx(Button, {
75766
+ ...itemRest,
75767
+ // bare, not discrete: what is drawn IS the dot and its
75768
+ // label — the hover wash a discrete button paints over its
75769
+ // whole surface is exactly what must not appear here (the
75770
+ // feedback is the circle over the dot, see the css).
75771
+ variant: "bare",
75772
+ className: "navi_step_list_step",
75773
+ "aria-current": index === currentIndex ? "step" : undefined,
75774
+ "data-current": index === currentIndex ? "" : undefined,
75775
+ readOnly: !travelByClick
75776
+ // Towards the slides when connected, by name: the command
75777
+ // reaches the container wherever this list sits on the
75778
+ // page. What else a press should do is the Item's own
75779
+ // onClick, which arrived through itemRest.
75780
+ ,
75781
+
75782
+ command: slideContainer && travelByClick ? `--navi-go-to-slide:${value}` : undefined,
75783
+ commandFor: slideContainer,
75784
+ children: jsx("span", {
75785
+ className: "navi_step_list_label",
75786
+ children: stepVNode
75787
+ })
75788
+ })
75789
+ }, value);
75790
+ })]
75791
+ }) : null
75792
+ });
75793
+ };
75794
+
75795
+ /**
75796
+ * One step of the walk: `value` names it (what `current`/`reached` say and
75797
+ * what a press reports), the children are its label. Rendered under its dot;
75798
+ * where the dot is, and what state it shows, is the StepList's business.
75799
+ *
75800
+ * It is both StepList.Item and an export of its own, the way Slide is to
75801
+ * SlideContainer.
75802
+ *
75803
+ * @type {import("ignore:preact").FunctionComponent<{
75804
+ * value: string,
75805
+ * [key: string]: any,
75806
+ * }>}
75807
+ */
75808
+ const Step = ({
75809
+ children
75810
+ }) => children;
75811
+ StepList.Item = Step;
75812
+
75244
75813
  installImportMetaCssBuild(import.meta);const css$1 = /* css */`
75245
75814
  @layer navi {
75246
75815
  .navi_viewport_layout {
@@ -75815,5 +76384,5 @@ const UserSvg = () => jsx("svg", {
75815
76384
  })
75816
76385
  });
75817
76386
 
75818
- export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, Expandable, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTransitionArea, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeRangeWheel, TimeSpin, TimeWheel, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, canNavBackSignal, canNavForwardSignal, coarsePointerSignal, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, defineRouteDefaultTransition, defineRouteTransition, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCanNavBack, useCanNavForward, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
76387
+ export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, Expandable, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTransitionArea, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, Step, StepList, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeRangeWheel, TimeSpin, TimeWheel, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, canNavBackSignal, canNavForwardSignal, coarsePointerSignal, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, defineRouteDefaultTransition, defineRouteTransition, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCanNavBack, useCanNavForward, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
75819
76388
  //# sourceMappingURL=jsenv_navi.js.map