@jsenv/navi 0.29.95 → 0.29.96

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,
@@ -27396,7 +27396,7 @@ const getAssociatedLabels = element => {
27396
27396
  return Array.from(element.labels);
27397
27397
  };
27398
27398
 
27399
- installImportMetaCssBuild(import.meta);const css$Z = /* css */`
27399
+ installImportMetaCssBuild(import.meta);const css$_ = /* css */`
27400
27400
  @layer navi {
27401
27401
  .navi_button {
27402
27402
  --button-border-radius: var(--navi-control-border-radius);
@@ -27827,7 +27827,7 @@ installImportMetaCssBuild(import.meta);const css$Z = /* css */`
27827
27827
  }
27828
27828
  `;
27829
27829
  const ButtonUI = props => {
27830
- import.meta.css = [css$Z, "@jsenv/navi/src/control/input/button_ui.jsx"];
27830
+ import.meta.css = [css$_, "@jsenv/navi/src/control/input/button_ui.jsx"];
27831
27831
  const {
27832
27832
  ref,
27833
27833
  // href/link
@@ -29538,7 +29538,7 @@ installImportMetaCssBuild(import.meta);/**
29538
29538
  * reaches the real container.
29539
29539
  */
29540
29540
  let openLocalDialogCount = 0;
29541
- const css$Y = /* css */`
29541
+ const css$Z = /* css */`
29542
29542
  @layer navi {
29543
29543
  .navi_dialog {
29544
29544
  /* Min gap between the dialog and the edges of its container. Written
@@ -30122,7 +30122,7 @@ const css$Y = /* css */`
30122
30122
  * @param {import("ignore:preact").ComponentChildren} props.children
30123
30123
  */
30124
30124
  const Dialog = props => {
30125
- import.meta.css = [css$Y, "@jsenv/navi/src/layout/dialog.jsx"];
30125
+ import.meta.css = [css$Z, "@jsenv/navi/src/layout/dialog.jsx"];
30126
30126
  if (props.openController) {
30127
30127
  return jsx(ControlledDialog, {
30128
30128
  ...props
@@ -31114,7 +31114,7 @@ installImportMetaCssBuild(import.meta);/**
31114
31114
  * and applied.
31115
31115
  */
31116
31116
  let openLocalPopoverCount = 0;
31117
- const css$X = /* css */`
31117
+ const css$Y = /* css */`
31118
31118
  @layer navi {
31119
31119
  .navi_popover {
31120
31120
  /* soft: user-configurable preferred max-height. Kept as a *default*
@@ -31570,7 +31570,7 @@ const css$X = /* css */`
31570
31570
  * @param {import("ignore:preact").ComponentChildren} props.children
31571
31571
  */
31572
31572
  const Popover = props => {
31573
- import.meta.css = [css$X, "@jsenv/navi/src/layout/popover.jsx"];
31573
+ import.meta.css = [css$Y, "@jsenv/navi/src/layout/popover.jsx"];
31574
31574
  if (props.openController) {
31575
31575
  return jsx(ControlledPopover, {
31576
31576
  ...props
@@ -32598,7 +32598,7 @@ installImportMetaCssBuild(import.meta);/**
32598
32598
  * event, and a caller replacing the body entirely then has one protocol to
32599
32599
  * follow — `--navi-confirm` for yes, anything that closes for no.
32600
32600
  */
32601
- const css$W = /* css */`
32601
+ const css$X = /* css */`
32602
32602
  /* The width lives on the body rather than on the popup, so that custom
32603
32603
  content (which replaces this body entirely) sizes itself instead of
32604
32604
  inheriting a ceiling meant for a sentence-long question. */
@@ -32735,7 +32735,7 @@ const ConfirmPopup = ({
32735
32735
  onAnswer,
32736
32736
  onClosed
32737
32737
  }) => {
32738
- import.meta.css = [css$W, "@jsenv/navi/src/action/confirm_popup.jsx"];
32738
+ import.meta.css = [css$X, "@jsenv/navi/src/action/confirm_popup.jsx"];
32739
32739
  const {
32740
32740
  mode,
32741
32741
  confirmLabel,
@@ -32819,7 +32819,7 @@ const defaultBody = (message, {
32819
32819
  });
32820
32820
  };
32821
32821
 
32822
- installImportMetaCssBuild(import.meta);const css$V = /* css */`
32822
+ installImportMetaCssBuild(import.meta);const css$W = /* css */`
32823
32823
  .action_error {
32824
32824
  margin-top: 0;
32825
32825
  margin-bottom: 20px;
@@ -32844,7 +32844,7 @@ const ActionRenderer = ({
32844
32844
  children,
32845
32845
  disabled
32846
32846
  }) => {
32847
- import.meta.css = [css$V, "@jsenv/navi/src/action/action_renderer.jsx"];
32847
+ import.meta.css = [css$W, "@jsenv/navi/src/action/action_renderer.jsx"];
32848
32848
  if (action === undefined) {
32849
32849
  throw new Error("ActionRenderer requires an action to render, but none was provided.");
32850
32850
  }
@@ -38588,7 +38588,7 @@ const ROUTE_TRAVEL_ATTRIBUTE = "data-navi-route-travel";
38588
38588
  // the root pictures must NOT move (they carry the whole viewport, blank bands
38589
38589
  // included).
38590
38590
 
38591
- const css$U = /* css */`
38591
+ const css$V = /* css */`
38592
38592
  /* The marked region is a picture of its own for the length of a transition of
38593
38593
  OURS, and only then — the name is what makes the pages a picture the
38594
38594
  movement below can carry.
@@ -39017,7 +39017,7 @@ const RouteTransitionArea = ({
39017
39017
  children,
39018
39018
  ...rest
39019
39019
  }) => {
39020
- import.meta.css = [css$U, "@jsenv/navi/src/nav/route_transition.jsx"];
39020
+ import.meta.css = [css$V, "@jsenv/navi/src/nav/route_transition.jsx"];
39021
39021
  const props = {
39022
39022
  ...rest,
39023
39023
  [TRANSITION_AREA_ATTRIBUTE]: ""
@@ -39074,7 +39074,7 @@ const RouteTransitionArea = ({
39074
39074
  * @returns {() => void} remove this relation.
39075
39075
  */
39076
39076
  const defineRouteTransition = (from, to, transition) => {
39077
- import.meta.css = [css$U, "@jsenv/navi/src/nav/route_transition.jsx"];
39077
+ import.meta.css = [css$V, "@jsenv/navi/src/nav/route_transition.jsx"];
39078
39078
  const {
39079
39079
  type,
39080
39080
  duration
@@ -39110,7 +39110,7 @@ const defineRouteTransition = (from, to, transition) => {
39110
39110
  * @returns {() => void} remove this default.
39111
39111
  */
39112
39112
  const defineRouteDefaultTransition = transition => {
39113
- import.meta.css = [css$U, "@jsenv/navi/src/nav/route_transition.jsx"];
39113
+ import.meta.css = [css$V, "@jsenv/navi/src/nav/route_transition.jsx"];
39114
39114
  const value = normalizeTransition(transition);
39115
39115
  defaultTransition = value;
39116
39116
  return () => {
@@ -39711,7 +39711,7 @@ const DRAGGED_ATTRIBUTE = "data-navi-route-travel-dragged";
39711
39711
  const TURNED_ATTRIBUTE = "data-navi-route-travel-turned";
39712
39712
  // The name the box wears while it travels, and only then (see nameForTravel).
39713
39713
  const TRAVEL_NAME = "navi-route-travel";
39714
- const css$T = /* css */`
39714
+ const css$U = /* css */`
39715
39715
  /* The name that makes the page inside this box a picture of its own during a
39716
39716
  transition — rather than part of the one big picture the document takes, so
39717
39717
  the two pages can move past each other while everything else stays where it
@@ -40101,7 +40101,7 @@ const RouteTravel = ({
40101
40101
  children,
40102
40102
  ...rest
40103
40103
  }) => {
40104
- import.meta.css = [css$T, "@jsenv/navi/src/nav/route_travel.jsx"];
40104
+ import.meta.css = [css$U, "@jsenv/navi/src/nav/route_travel.jsx"];
40105
40105
  const elementRef = useRef();
40106
40106
  const gestureRef = useRef(null);
40107
40107
  // The travel in hand: the transition keeping the picture of the page being
@@ -42663,7 +42663,7 @@ const PhoneSvg = () => {
42663
42663
  };
42664
42664
 
42665
42665
  installImportMetaCssBuild(import.meta);// # TextAnchor — how it works
42666
- const css$S = /* css */`
42666
+ const css$T = /* css */`
42667
42667
  .navi_text_anchor {
42668
42668
  vertical-align: baseline;
42669
42669
  user-select: none;
@@ -42698,7 +42698,7 @@ const TextAnchor = ({
42698
42698
  textSize,
42699
42699
  lineLayout
42700
42700
  }) => {
42701
- import.meta.css = [css$S, "@jsenv/navi/src/text/text_anchor.jsx"];
42701
+ import.meta.css = [css$T, "@jsenv/navi/src/text/text_anchor.jsx"];
42702
42702
  const anchorRef = useRef();
42703
42703
 
42704
42704
  // Plain useLayoutEffect would also fire while an ancestor dialog/popover
@@ -42813,7 +42813,7 @@ const computeTopOffset = ({
42813
42813
  };
42814
42814
  const charTopCanvas = document.createElement("canvas");
42815
42815
 
42816
- installImportMetaCssBuild(import.meta);const css$R = /* css */`
42816
+ installImportMetaCssBuild(import.meta);const css$S = /* css */`
42817
42817
  @layer navi {
42818
42818
  /* Ensure data attributes from box.jsx can win to update display */
42819
42819
  .navi_icon {
@@ -42971,7 +42971,7 @@ const Icon = ({
42971
42971
  fillLine,
42972
42972
  ...props
42973
42973
  }) => {
42974
- import.meta.css = [css$R, "@jsenv/navi/src/text/icon.jsx"];
42974
+ import.meta.css = [css$S, "@jsenv/navi/src/text/icon.jsx"];
42975
42975
  const innerChildren = href ? jsx("svg", {
42976
42976
  width: "100%",
42977
42977
  height: "100%",
@@ -43133,7 +43133,7 @@ const useDimColorWhen = (elementRef, shouldDim) => {
43133
43133
  });
43134
43134
  };
43135
43135
 
43136
- installImportMetaCssBuild(import.meta);const css$Q = /* css */`
43136
+ installImportMetaCssBuild(import.meta);const css$R = /* css */`
43137
43137
  @layer navi {
43138
43138
  .navi_link {
43139
43139
  --link-border-radius: unset;
@@ -43595,7 +43595,7 @@ Object.assign(PSEUDO_CLASSES, {
43595
43595
  * @param {boolean} [props.readOnly]
43596
43596
  */
43597
43597
  const Link = props => {
43598
- import.meta.css = [css$Q, "@jsenv/navi/src/nav/link/link.jsx"];
43598
+ import.meta.css = [css$R, "@jsenv/navi/src/nav/link/link.jsx"];
43599
43599
  if (props.route) {
43600
43600
  return jsx(LinkWithRoute, {
43601
43601
  ...props
@@ -43918,7 +43918,7 @@ installImportMetaCssBuild(import.meta);/**
43918
43918
  * https://dribbble.com/search/tabs
43919
43919
  */
43920
43920
  let navCount = 0;
43921
- const css$P = /* css */`
43921
+ const css$Q = /* css */`
43922
43922
  @layer navi {
43923
43923
  .navi_nav {
43924
43924
  --nav-border: none;
@@ -44201,7 +44201,7 @@ const Nav = ({
44201
44201
  slideContainer,
44202
44202
  ...props
44203
44203
  }) => {
44204
- import.meta.css = [css$P, "@jsenv/navi/src/nav/link/nav.jsx"];
44204
+ import.meta.css = [css$Q, "@jsenv/navi/src/nav/link/nav.jsx"];
44205
44205
  const defaultRef = useRef();
44206
44206
  props.ref = props.ref || defaultRef;
44207
44207
  const navRef = props.ref;
@@ -44728,7 +44728,7 @@ installImportMetaCssBuild(import.meta);/**
44728
44728
  * Border width participates in layout (it is added to the tab and page
44729
44729
  * padding): a thick border grows the binder rather than eating into the text.
44730
44730
  */
44731
- const css$O = /* css */`
44731
+ const css$P = /* css */`
44732
44732
  @layer navi {
44733
44733
  .navi_binder {
44734
44734
  --binder-border-width: var(--navi-control-border-width);
@@ -45041,7 +45041,7 @@ const Binder = ({
45041
45041
  pagePadding,
45042
45042
  ...props
45043
45043
  }) => {
45044
- import.meta.css = [css$O, "@jsenv/navi/src/nav/binder/binder.jsx"];
45044
+ import.meta.css = [css$P, "@jsenv/navi/src/nav/binder/binder.jsx"];
45045
45045
  const items = toChildArray(children).map((child, index) => {
45046
45046
  const {
45047
45047
  value: itemValue,
@@ -45528,7 +45528,7 @@ installImportMetaCssBuild(import.meta);/**
45528
45528
  * added to the size asked for exactly like the notch inset is, so the
45529
45529
  * content still gets the size the prop names.
45530
45530
  */
45531
- const css$N = /* css */`
45531
+ const css$O = /* css */`
45532
45532
  @layer navi {
45533
45533
  :root {
45534
45534
  --navi-fixed-bar-width: 56px;
@@ -45676,7 +45676,7 @@ const FixedBar = ({
45676
45676
  border = true,
45677
45677
  ...props
45678
45678
  }) => {
45679
- import.meta.css = [css$N, "@jsenv/navi/src/layout/fixed_bar/fixed_bar.jsx"];
45679
+ import.meta.css = [css$O, "@jsenv/navi/src/layout/fixed_bar/fixed_bar.jsx"];
45680
45680
  const defaultRef = useRef();
45681
45681
  props.ref = props.ref || defaultRef;
45682
45682
  // Said with the width the border rule reads rather than with an attribute of
@@ -45770,7 +45770,7 @@ const FixedBar = ({
45770
45770
  // Subpixel layout rounds rectangles up on boxes that fit exactly.
45771
45771
  const OVERFLOW_TOLERANCE = 1;
45772
45772
 
45773
- const css$M = /* css */ `
45773
+ const css$N = /* css */ `
45774
45774
  [data-navi-overflow-x] {
45775
45775
  outline: 2px dashed #e74c3c;
45776
45776
  outline-offset: -2px;
@@ -45794,7 +45794,7 @@ const detectHorizontalOverflow = ({
45794
45794
  let styleEl = null;
45795
45795
  if (highlight) {
45796
45796
  styleEl = document.createElement("style");
45797
- styleEl.textContent = css$M;
45797
+ styleEl.textContent = css$N;
45798
45798
  document.head.appendChild(styleEl);
45799
45799
  }
45800
45800
 
@@ -45949,7 +45949,7 @@ const useFocusGroup = (
45949
45949
  };
45950
45950
 
45951
45951
  installImportMetaCssBuild(import.meta);const rightArrowPath = "M680-480L360-160l-80-80 240-240-240-240 80-80 320 320z";
45952
- const css$L = /* css */`
45952
+ const css$M = /* css */`
45953
45953
  .navi_summary_marker {
45954
45954
  width: 1em;
45955
45955
  height: 1em;
@@ -46039,7 +46039,7 @@ const SummaryMarker = ({
46039
46039
  loading,
46040
46040
  openDirection = "down"
46041
46041
  }) => {
46042
- import.meta.css = [css$L, "@jsenv/navi/src/control/details/summary_marker.jsx"];
46042
+ import.meta.css = [css$M, "@jsenv/navi/src/control/details/summary_marker.jsx"];
46043
46043
  const showLoading = useDebounceTrue(loading, 300);
46044
46044
  return jsx("span", {
46045
46045
  className: "navi_summary_marker",
@@ -46084,7 +46084,7 @@ const SummaryMarker = ({
46084
46084
  });
46085
46085
  };
46086
46086
 
46087
- installImportMetaCssBuild(import.meta);const css$K = /* css */`
46087
+ installImportMetaCssBuild(import.meta);const css$L = /* css */`
46088
46088
  .navi_details {
46089
46089
  position: relative;
46090
46090
  z-index: 1;
@@ -46130,7 +46130,7 @@ const Details = props => {
46130
46130
  return details;
46131
46131
  };
46132
46132
  const DetailsField = props => {
46133
- import.meta.css = [css$K, "@jsenv/navi/src/control/details/details.jsx"];
46133
+ import.meta.css = [css$L, "@jsenv/navi/src/control/details/details.jsx"];
46134
46134
  const {
46135
46135
  ref,
46136
46136
  persists,
@@ -46350,7 +46350,7 @@ installImportMetaCssBuild(import.meta);/**
46350
46350
  * UI when it comes first). Once settled open the clipping is released, so a
46351
46351
  * popover or focus ring inside is not cut at the edges.
46352
46352
  */
46353
- const css$J = /* css */`
46353
+ const css$K = /* css */`
46354
46354
  .navi_expandable {
46355
46355
  position: relative;
46356
46356
  display: flex;
@@ -46576,7 +46576,7 @@ const useExpandableContext = partName => {
46576
46576
  * and rebuilds it from scratch on every expansion.
46577
46577
  */
46578
46578
  const Expandable = props => {
46579
- import.meta.css = [css$J, "@jsenv/navi/src/control/expandable/expandable.jsx"];
46579
+ import.meta.css = [css$K, "@jsenv/navi/src/control/expandable/expandable.jsx"];
46580
46580
  const {
46581
46581
  ref,
46582
46582
  ui,
@@ -47241,7 +47241,7 @@ const ControlGroup = props => {
47241
47241
  };
47242
47242
  const CONTROL_GROUP_PSEUDO_CLASSES = [":hover", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading"];
47243
47243
 
47244
- installImportMetaCssBuild(import.meta);const css$I = /* css */`
47244
+ installImportMetaCssBuild(import.meta);const css$J = /* css */`
47245
47245
  @layer navi {
47246
47246
  .navi_checkbox {
47247
47247
  --switch-margin: 0; /* Useful to reserve space for outline */
@@ -47319,7 +47319,7 @@ installImportMetaCssBuild(import.meta);const css$I = /* css */`
47319
47319
  }
47320
47320
  `;
47321
47321
  const SwitchUI = () => {
47322
- import.meta.css = [css$I, "@jsenv/navi/src/control/input/switch_ui.jsx"];
47322
+ import.meta.css = [css$J, "@jsenv/navi/src/control/input/switch_ui.jsx"];
47323
47323
  return jsx(Box, {
47324
47324
  className: "navi_switch",
47325
47325
  as: "svg",
@@ -47361,7 +47361,7 @@ const useCheckableProps = (props, options) => {
47361
47361
  return result;
47362
47362
  };
47363
47363
 
47364
- installImportMetaCssBuild(import.meta);const css$H = /* css */`
47364
+ installImportMetaCssBuild(import.meta);const css$I = /* css */`
47365
47365
  @layer navi {
47366
47366
  .navi_checkbox {
47367
47367
  --border-radius: var(--navi-checkbox-border-radius);
@@ -47688,7 +47688,7 @@ const InputCheckboxHeadless = props => {
47688
47688
  });
47689
47689
  };
47690
47690
  const InputCheckboxFieldInterface = props => {
47691
- import.meta.css = [css$H, "@jsenv/navi/src/control/input/input_checkbox.jsx"];
47691
+ import.meta.css = [css$I, "@jsenv/navi/src/control/input/input_checkbox.jsx"];
47692
47692
  const [checkboxRootProps, checkboxHostProps] = useCheckableProps(props);
47693
47693
  const {
47694
47694
  icon,
@@ -47810,7 +47810,7 @@ const CheckboxButtonStyleCSSVars = {
47810
47810
  const CheckboxPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":checked", ":-navi-loading"];
47811
47811
  const CheckboxPseudoElements = ["::-navi-loader", "::-navi-checkmark"];
47812
47812
 
47813
- installImportMetaCssBuild(import.meta);const css$G = /* css */`
47813
+ installImportMetaCssBuild(import.meta);const css$H = /* css */`
47814
47814
  @layer navi {
47815
47815
  .navi_label {
47816
47816
  --label-required-indicator-color: var(--navi-color-danger, #b42318);
@@ -47890,7 +47890,7 @@ installImportMetaCssBuild(import.meta);const css$G = /* css */`
47890
47890
  * </Field>
47891
47891
  */
47892
47892
  const Field = props => {
47893
- import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
47893
+ import.meta.css = [css$H, "@jsenv/navi/src/control/field.jsx"];
47894
47894
  const refDefault = useRef();
47895
47895
  props.ref = props.ref || refDefault;
47896
47896
  const {
@@ -47925,7 +47925,7 @@ const FieldCSSVars = {
47925
47925
  spacingWithControl: "--spacing-with-control"
47926
47926
  };
47927
47927
  const FieldAsContainer = props => {
47928
- import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
47928
+ import.meta.css = [css$H, "@jsenv/navi/src/control/field.jsx"];
47929
47929
  const {
47930
47930
  children
47931
47931
  } = props;
@@ -47957,7 +47957,7 @@ const FieldAsContainer = props => {
47957
47957
  };
47958
47958
  const FIELD_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading"];
47959
47959
  const Label = props => {
47960
- import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
47960
+ import.meta.css = [css$H, "@jsenv/navi/src/control/field.jsx"];
47961
47961
  const {
47962
47962
  children,
47963
47963
  // Marks the label when its control is required. Takes what to show, or
@@ -48119,7 +48119,7 @@ const InputSlot = ({
48119
48119
  });
48120
48120
  };
48121
48121
 
48122
- installImportMetaCssBuild(import.meta);const css$F = /* css */`
48122
+ installImportMetaCssBuild(import.meta);const css$G = /* css */`
48123
48123
  @layer navi {
48124
48124
  .navi_radio {
48125
48125
  --margin: 3px 3px 3px 5px;
@@ -48482,7 +48482,7 @@ const InputRadioHeadless = props => {
48482
48482
  };
48483
48483
  const VARIANT_SET = new Set(["icon", "button", "radio"]);
48484
48484
  const InputRadioFieldInterface = props => {
48485
- import.meta.css = [css$F, "@jsenv/navi/src/control/input/input_radio.jsx"];
48485
+ import.meta.css = [css$G, "@jsenv/navi/src/control/input/input_radio.jsx"];
48486
48486
  const [radioRootProps, radioHostProps] = useCheckableProps(props);
48487
48487
  const {
48488
48488
  icon,
@@ -48628,7 +48628,7 @@ const RadioButtonStyleCSSVars = {
48628
48628
  const RadioPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":checked", ":-navi-loading"];
48629
48629
  const RadioPseudoElements = ["::-navi-loader", "::-navi-radiomark"];
48630
48630
 
48631
- installImportMetaCssBuild(import.meta);const css$E = /* css */`
48631
+ installImportMetaCssBuild(import.meta);const css$F = /* css */`
48632
48632
  @layer navi {
48633
48633
  .navi_input_range {
48634
48634
  --border-radius: 6px;
@@ -48883,7 +48883,7 @@ const InputRange = props => {
48883
48883
  });
48884
48884
  };
48885
48885
  const InputRangeFieldInterface = props => {
48886
- import.meta.css = [css$E, "@jsenv/navi/src/control/input/input_range.jsx"];
48886
+ import.meta.css = [css$F, "@jsenv/navi/src/control/input/input_range.jsx"];
48887
48887
  const {
48888
48888
  ref
48889
48889
  } = props;
@@ -50991,7 +50991,7 @@ installImportMetaCssBuild(import.meta);/**
50991
50991
  * This means an editable thing MUST have a parent with position relative that wraps the content and the eventual editable input
50992
50992
  *
50993
50993
  */
50994
- const css$D = /* css */`
50994
+ const css$E = /* css */`
50995
50995
  .navi_editable_wrapper {
50996
50996
  --inset-top: 0px;
50997
50997
  --inset-right: 0px;
@@ -51040,7 +51040,7 @@ const useEditionController = () => {
51040
51040
  };
51041
51041
  };
51042
51042
  const Editable = props => {
51043
- import.meta.css = [css$D, "@jsenv/navi/src/control/edition/editable.jsx"];
51043
+ import.meta.css = [css$E, "@jsenv/navi/src/control/edition/editable.jsx"];
51044
51044
  let {
51045
51045
  children,
51046
51046
  action,
@@ -51589,7 +51589,7 @@ installImportMetaCssBuild(import.meta);/**
51589
51589
  * meet are drawn once instead of twice, and only the outer corners stay
51590
51590
  * rounded. See docs/control_group.md.
51591
51591
  */
51592
- const css$C = /* css */`
51592
+ const css$D = /* css */`
51593
51593
  .navi_group {
51594
51594
  --group-border-width: var(--navi-control-border-width);
51595
51595
 
@@ -51705,7 +51705,7 @@ const Group = ({
51705
51705
  vertical = row,
51706
51706
  ...props
51707
51707
  }) => {
51708
- import.meta.css = [css$C, "@jsenv/navi/src/control/group.jsx"];
51708
+ import.meta.css = [css$D, "@jsenv/navi/src/control/group.jsx"];
51709
51709
  return jsx(Box, {
51710
51710
  baseClassName: "navi_group",
51711
51711
  "data-vertical": vertical ? "" : undefined
@@ -51871,7 +51871,7 @@ installImportMetaCssBuild(import.meta);/**
51871
51871
  * So: nothing scrollable between the cap and the slides (a shared [data-body]
51872
51872
  * around them IS a scroller, see box.jsx), and `overflow="auto"` on each Slide.
51873
51873
  */
51874
- const css$B = /* css */`
51874
+ const css$C = /* css */`
51875
51875
  /* Where the picture stands relative to the slide that is current, in boxes
51876
51876
  (see paintTravelProgress). Declared, so that it is a NUMBER the browser can
51877
51877
  interpolate: the trait an indicator draws has to travel with the slides,
@@ -52365,7 +52365,7 @@ const SlideContainer = ({
52365
52365
  children,
52366
52366
  ...rest
52367
52367
  }) => {
52368
- import.meta.css = [css$B, "@jsenv/navi/src/layout/slide_container.jsx"];
52368
+ import.meta.css = [css$C, "@jsenv/navi/src/layout/slide_container.jsx"];
52369
52369
  const debugFocus = useDebugFocus();
52370
52370
  const trackRef = useRef();
52371
52371
  // The box itself: it is what takes the keyboard when what is on screen holds
@@ -55210,7 +55210,7 @@ installImportMetaCssBuild(import.meta);/**
55210
55210
  * and only under its own `sizeFromAnchor`) pass through untouched via
55211
55211
  * `...rest` to whichever of Popover/Dialog actually renders.
55212
55212
  */
55213
- const css$A = /* css */`
55213
+ const css$B = /* css */`
55214
55214
  @layer navi {
55215
55215
  .navi_popup {
55216
55216
  --popup-border-radius: var(--navi-popup-border-radius);
@@ -55327,7 +55327,7 @@ const css$A = /* css */`
55327
55327
  * @param {import("ignore:preact").ComponentChildren} props.children
55328
55328
  */
55329
55329
  const Popup = props => {
55330
- import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
55330
+ import.meta.css = [css$B, "@jsenv/navi/src/layout/popup.jsx"];
55331
55331
  const {
55332
55332
  mode: modeProp,
55333
55333
  maxWidth,
@@ -55388,7 +55388,7 @@ const Popup = props => {
55388
55388
  });
55389
55389
  };
55390
55390
 
55391
- installImportMetaCssBuild(import.meta);const css$z = /* css */`
55391
+ installImportMetaCssBuild(import.meta);const css$A = /* css */`
55392
55392
  .navi_picker {
55393
55393
  /* Sizing ceilings (maxmax), background, box-shadow, outline, padding,
55394
55394
  overflow... are already handled correctly by Popup/Popover/Dialog
@@ -55516,7 +55516,7 @@ installImportMetaCssBuild(import.meta);const css$z = /* css */`
55516
55516
  }
55517
55517
  `;
55518
55518
  const PickerCustomResolver = props => {
55519
- import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
55519
+ import.meta.css = [css$A, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
55520
55520
  if (props.children === undefined) {
55521
55521
  return jsx(PickerNative, {
55522
55522
  ...props
@@ -56310,7 +56310,7 @@ const LoadingIndicator = ({
56310
56310
  });
56311
56311
  };
56312
56312
 
56313
- installImportMetaCssBuild(import.meta);const css$y = /* css */`
56313
+ installImportMetaCssBuild(import.meta);const css$z = /* css */`
56314
56314
  @layer navi {
56315
56315
  .navi_separator {
56316
56316
  --size: 1px;
@@ -56388,7 +56388,7 @@ const Separator = ({
56388
56388
  style,
56389
56389
  ...props
56390
56390
  }) => {
56391
- import.meta.css = [css$y, "@jsenv/navi/src/layout/separator.jsx"];
56391
+ import.meta.css = [css$z, "@jsenv/navi/src/layout/separator.jsx"];
56392
56392
  return jsx(Box, {
56393
56393
  as: vertical ? "span" : "hr",
56394
56394
  ...props,
@@ -56881,7 +56881,7 @@ const ListItemFooter = props => {
56881
56881
  });
56882
56882
  };
56883
56883
 
56884
- installImportMetaCssBuild(import.meta);const css$x = /* css */`
56884
+ installImportMetaCssBuild(import.meta);const css$y = /* css */`
56885
56885
  @layer navi {
56886
56886
  .navi_list_container[navi-selectable] {
56887
56887
  /* Focus outline */
@@ -57093,7 +57093,7 @@ const ListSelectableResolver = props => {
57093
57093
  };
57094
57094
  const ListSelectable = props => {
57095
57095
  const Next = useNextResolver();
57096
- import.meta.css = [css$x, "@jsenv/navi/src/control/list/list_selectable.jsx"];
57096
+ import.meta.css = [css$y, "@jsenv/navi/src/control/list/list_selectable.jsx"];
57097
57097
  // we allow ourselves to auto-generate a name
57098
57098
  const defaultName = useId();
57099
57099
  props.name = props.name || `listbox_${defaultName}`;
@@ -57713,7 +57713,7 @@ const ListVirtualContext = createContext(null);
57713
57713
  // that returning a component of one's own — instead of a bare <List.Item> —
57714
57714
  // works the same way.
57715
57715
  const ListRowContext = createContext(null);
57716
- const css$w = /* css */`
57716
+ const css$x = /* css */`
57717
57717
  @layer navi {
57718
57718
  .navi_list_container {
57719
57719
  --list-outline-width: 1px;
@@ -58412,7 +58412,7 @@ const css$w = /* css */`
58412
58412
  }
58413
58413
  `;
58414
58414
  const ListUI = props => {
58415
- import.meta.css = [css$w, "@jsenv/navi/src/control/list/list.jsx"];
58415
+ import.meta.css = [css$x, "@jsenv/navi/src/control/list/list.jsx"];
58416
58416
  const {
58417
58417
  ref,
58418
58418
  renderBudget: renderBudgetProp = RENDER_BUDGET_DEFAULT,
@@ -62081,7 +62081,7 @@ const PickerPresetResolver = props => {
62081
62081
  });
62082
62082
  };
62083
62083
 
62084
- installImportMetaCssBuild(import.meta);const css$v = /* css */`
62084
+ installImportMetaCssBuild(import.meta);const css$w = /* css */`
62085
62085
  @layer navi {
62086
62086
  }
62087
62087
  .navi_badge {
@@ -62193,7 +62193,7 @@ const Badge = ({
62193
62193
  className,
62194
62194
  ...props
62195
62195
  }) => {
62196
- import.meta.css = [css$v, "@jsenv/navi/src/text/badge.jsx"];
62196
+ import.meta.css = [css$w, "@jsenv/navi/src/text/badge.jsx"];
62197
62197
  const defaultRef = useRef();
62198
62198
  props.ref = props.ref || defaultRef;
62199
62199
  const {
@@ -62245,7 +62245,7 @@ const BadgeButton = props => {
62245
62245
  };
62246
62246
  Badge.Button = BadgeButton;
62247
62247
 
62248
- installImportMetaCssBuild(import.meta);const css$u = /* css */`
62248
+ installImportMetaCssBuild(import.meta);const css$v = /* css */`
62249
62249
  @layer navi {
62250
62250
  }
62251
62251
  .navi_badge_list {
@@ -62270,7 +62270,7 @@ const BadgeList = ({
62270
62270
  max,
62271
62271
  ...props
62272
62272
  }) => {
62273
- import.meta.css = [css$u, "@jsenv/navi/src/text/badge_list.jsx"];
62273
+ import.meta.css = [css$v, "@jsenv/navi/src/text/badge_list.jsx"];
62274
62274
  const measureRef = useRef();
62275
62275
  const visibleRef = useRef();
62276
62276
  useLayoutEffect(() => {
@@ -62345,7 +62345,7 @@ const BadgeList = ({
62345
62345
  });
62346
62346
  };
62347
62347
 
62348
- installImportMetaCssBuild(import.meta);const css$t = /* css */`
62348
+ installImportMetaCssBuild(import.meta);const css$u = /* css */`
62349
62349
  .navi_color {
62350
62350
  display: block;
62351
62351
  aspect-ratio: 1/1;
@@ -62376,7 +62376,7 @@ const Color = ({
62376
62376
  children,
62377
62377
  ...rest
62378
62378
  }) => {
62379
- import.meta.css = [css$t, "@jsenv/navi/src/text/color.jsx"];
62379
+ import.meta.css = [css$u, "@jsenv/navi/src/text/color.jsx"];
62380
62380
  const color = children || undefined;
62381
62381
  return jsx(Box, {
62382
62382
  as: "span",
@@ -62833,7 +62833,7 @@ const PickerFileUI = () => {
62833
62833
  return String(value);
62834
62834
  };
62835
62835
 
62836
- installImportMetaCssBuild(import.meta);const css$s = /* css */`
62836
+ installImportMetaCssBuild(import.meta);const css$t = /* css */`
62837
62837
  @layer navi {
62838
62838
  .navi_picker {
62839
62839
  --picker-border-radius: var(--navi-control-border-radius);
@@ -63222,7 +63222,7 @@ installImportMetaCssBuild(import.meta);const css$s = /* css */`
63222
63222
  }
63223
63223
  `;
63224
63224
  const PickerButton = props => {
63225
- import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker.jsx"];
63225
+ import.meta.css = [css$t, "@jsenv/navi/src/control/picker/picker.jsx"];
63226
63226
  if (typeof props.maxLines === "string") {
63227
63227
  props.maxLines = parseInt(props.maxLines);
63228
63228
  }
@@ -63671,7 +63671,7 @@ installImportMetaCssBuild(import.meta);/**
63671
63671
  * refuse it on purpose, which is what keeps the focus where the travel happens
63672
63672
  * instead of moving it into a slide that is about to leave.
63673
63673
  */
63674
- const css$r = /* css */`
63674
+ const css$s = /* css */`
63675
63675
  @layer navi {
63676
63676
  .navi_picker_spin {
63677
63677
  /* A picker one steps through is still a picker: what themes every picker
@@ -64140,7 +64140,7 @@ const Spin = ({
64140
64140
  nextLabel,
64141
64141
  ...rest
64142
64142
  }) => {
64143
- import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64143
+ import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64144
64144
  const id = useId();
64145
64145
  // What the group around it says, when there is one: how big the whole thing
64146
64146
  // is written is said once, on the group, and every spin in it follows.
@@ -64676,7 +64676,7 @@ const renderValueDefault = value => String(value ?? "");
64676
64676
  * are passed on to the spins sitting in them.
64677
64677
  */
64678
64678
  const SpinGroup = props => {
64679
- import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64679
+ import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
64680
64680
  const {
64681
64681
  size
64682
64682
  } = props;
@@ -65189,7 +65189,7 @@ const TimeRangeSpin = ({
65189
65189
  };
65190
65190
 
65191
65191
  installImportMetaCssBuild(import.meta);// TOFIX: select in data then reset, it reset to red/blue instead of red/blue/green
65192
- const css$q = /* css */`
65192
+ const css$r = /* css */`
65193
65193
  .navi_checkbox_group {
65194
65194
  border-style: solid;
65195
65195
 
@@ -65230,7 +65230,7 @@ const CheckboxGroup = props => {
65230
65230
  return checkboxGroup;
65231
65231
  };
65232
65232
  const CheckboxGroupInterface = props => {
65233
- import.meta.css = [css$q, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
65233
+ import.meta.css = [css$r, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
65234
65234
  const {
65235
65235
  ref
65236
65236
  } = props;
@@ -65279,7 +65279,7 @@ installImportMetaCssBuild(import.meta);/**
65279
65279
  * shared sheet is registered here too — a page may render a Textarea without
65280
65280
  * any Input.
65281
65281
  */
65282
- const css$p = /* css */`
65282
+ const css$q = /* css */`
65283
65283
  .navi_input.navi_textarea {
65284
65284
  .navi_control_input {
65285
65285
  min-height: calc(var(--textarea-min-rows, 1.5) * 1lh);
@@ -65366,7 +65366,7 @@ const Textarea = ({
65366
65366
  width = "35ch",
65367
65367
  ...props
65368
65368
  }) => {
65369
- import.meta.css = [inputCss + css$p, "@jsenv/navi/src/control/input/textarea.jsx"];
65369
+ import.meta.css = [inputCss + css$q, "@jsenv/navi/src/control/input/textarea.jsx"];
65370
65370
  const defaultRef = useRef(null);
65371
65371
  props.ref = props.ref || defaultRef;
65372
65372
  usePlaceholderHeight(props.ref, props.placeholder);
@@ -65440,7 +65440,7 @@ const TextareaCharCount = ({
65440
65440
  maxLength,
65441
65441
  ...rest
65442
65442
  }) => {
65443
- import.meta.css = [css$p, "@jsenv/navi/src/control/input/textarea.jsx"];
65443
+ import.meta.css = [css$q, "@jsenv/navi/src/control/input/textarea.jsx"];
65444
65444
  const resolvedValue = signal ? signal.value : value;
65445
65445
  const length = typeof resolvedValue === "string" ? resolvedValue.length : 0;
65446
65446
  return jsx(Box, {
@@ -65625,7 +65625,7 @@ const formatIntlUnit = (unit, {
65625
65625
  }
65626
65626
  };
65627
65627
 
65628
- installImportMetaCssBuild(import.meta);const css$o = /* css */`
65628
+ installImportMetaCssBuild(import.meta);const css$p = /* css */`
65629
65629
  .navi_input_duration {
65630
65630
  --duration-separator-spacing: 4px;
65631
65631
  --loader-color: var(--navi-loader-color);
@@ -65692,7 +65692,7 @@ installImportMetaCssBuild(import.meta);const css$o = /* css */`
65692
65692
  * "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
65693
65693
  */
65694
65694
  const InputDuration = props => {
65695
- import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
65695
+ import.meta.css = [css$p, "@jsenv/navi/src/control/input/input_duration.jsx"];
65696
65696
  const defaultRef = useRef();
65697
65697
  props.ref = props.ref || defaultRef;
65698
65698
  props.max = props.max || "23h59";
@@ -66194,7 +66194,7 @@ const InputDurationPart = ({
66194
66194
  });
66195
66195
  };
66196
66196
 
66197
- installImportMetaCssBuild(import.meta);const css$n = /* css */`
66197
+ installImportMetaCssBuild(import.meta);const css$o = /* css */`
66198
66198
  .navi_radio_group {
66199
66199
  border-style: solid;
66200
66200
 
@@ -66214,7 +66214,7 @@ const RadioGroup = props => {
66214
66214
  return radioGroup;
66215
66215
  };
66216
66216
  const RadioGroupInterface = props => {
66217
- import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
66217
+ import.meta.css = [css$o, "@jsenv/navi/src/control/input/radio_group.jsx"];
66218
66218
  const {
66219
66219
  ref
66220
66220
  } = props;
@@ -66272,7 +66272,7 @@ installImportMetaCssBuild(import.meta);/**
66272
66272
  * control is drawn — the list it opens stays the platform's own, which is the
66273
66273
  * whole point of using a select.
66274
66274
  */
66275
- const css$m = /* css */`
66275
+ const css$n = /* css */`
66276
66276
  .navi_input.navi_select {
66277
66277
  .navi_control_input {
66278
66278
  /* Room for the chevron, which sits over the padding rather than beside
@@ -66327,7 +66327,7 @@ const Select = ({
66327
66327
  multiple,
66328
66328
  ...props
66329
66329
  }) => {
66330
- import.meta.css = [inputCss + css$m, "@jsenv/navi/src/control/input/select.jsx"];
66330
+ import.meta.css = [inputCss + css$n, "@jsenv/navi/src/control/input/select.jsx"];
66331
66331
  const defaultRef = useRef(null);
66332
66332
  props.ref = props.ref || defaultRef;
66333
66333
  seedDefaultValueFromSignal(props);
@@ -66395,7 +66395,7 @@ installImportMetaCssBuild(import.meta);/**
66395
66395
  * running: one loading outline around both, which is why each half is told
66396
66396
  * `loadingOutline={false}`.
66397
66397
  */
66398
- const css$l = /* css */`
66398
+ const css$m = /* css */`
66399
66399
  /* Around the pair rather than in it: the outline is drawn against this
66400
66400
  element and follows its corners, and a Group counts its own children to
66401
66401
  know which corners to square — an outline among them would be one of the
@@ -66507,7 +66507,7 @@ const css$l = /* css */`
66507
66507
  * Anything else lands on the split button's own box.
66508
66508
  */
66509
66509
  const SplitButton = props => {
66510
- import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
66510
+ import.meta.css = [css$m, "@jsenv/navi/src/control/input/split_button.jsx"];
66511
66511
  const {
66512
66512
  options = [],
66513
66513
  value,
@@ -67158,7 +67158,7 @@ installImportMetaCssBuild(import.meta);/*
67158
67158
  * accessors (top/height vs left/width) chosen from `horizontal`, and the CSS has
67159
67159
  * a [data-horizontal] variant.
67160
67160
  */
67161
- const css$k = /* css */`
67161
+ const css$l = /* css */`
67162
67162
  .navi_wheel_container {
67163
67163
  /* Row size and emphasis band are read together: the band is what a value
67164
67164
  must cross to lose its emphasis, and the row is how far it has to travel
@@ -68280,7 +68280,7 @@ const useWheelKeyboard = ({
68280
68280
  }, [isHorizontal, interactive, isLoop]);
68281
68281
  };
68282
68282
  function WheelUI(props) {
68283
- import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
68283
+ import.meta.css = [css$l, "@jsenv/navi/src/control/wheel/wheel.jsx"];
68284
68284
  const {
68285
68285
  ref,
68286
68286
  visibleCount = 3,
@@ -69189,7 +69189,7 @@ Wheel.Item = WheelItem;
69189
69189
  * @param {boolean} [props.zoom] - Enlarge the centered value of every wheel (see Wheel's zoom prop) with one prop for the whole group.
69190
69190
  */
69191
69191
  const WheelGroup = props => {
69192
- import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
69192
+ import.meta.css = [css$l, "@jsenv/navi/src/control/wheel/wheel.jsx"];
69193
69193
  // WheelGroup IS a control group: it aggregates its named wheels ("hours",
69194
69194
  // "minutes"…) into one object value, so it can sit directly inside a Form or a
69195
69195
  // Picker with no extra <ControlGroup> wrapper. The wheel-specific presentation
@@ -70054,7 +70054,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
70054
70054
 
70055
70055
  const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
70056
70056
 
70057
- installImportMetaCssBuild(import.meta);const css$j = /* css */`
70057
+ installImportMetaCssBuild(import.meta);const css$k = /* css */`
70058
70058
  .navi_table_drag_clone_container {
70059
70059
  position: absolute;
70060
70060
  top: var(--table-visual-top);
@@ -70209,7 +70209,7 @@ const useTableDragContextValue = ({
70209
70209
  }, [grabTarget, canChangeColumnOrder]);
70210
70210
  };
70211
70211
  const TableDragCloneContainer = forwardRef((props, ref) => {
70212
- import.meta.css = [css$j, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
70212
+ import.meta.css = [css$k, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
70213
70213
  const {
70214
70214
  tableId
70215
70215
  } = props;
@@ -70507,7 +70507,7 @@ installImportMetaCssBuild(import.meta);const ROW_MIN_HEIGHT = 30;
70507
70507
  const ROW_MAX_HEIGHT = 100;
70508
70508
  const COLUMN_MIN_WIDTH = 50;
70509
70509
  const COLUMN_MAX_WIDTH = 500;
70510
- const css$i = /* css */`
70510
+ const css$j = /* css */`
70511
70511
  @layer navi {
70512
70512
  .navi_table {
70513
70513
  --table-resizer-handle-color: #063b7c;
@@ -70667,7 +70667,7 @@ const css$i = /* css */`
70667
70667
 
70668
70668
  // Column resize components
70669
70669
  const TableColumnResizer = props => {
70670
- import.meta.css = [css$i, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
70670
+ import.meta.css = [css$j, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
70671
70671
  const defaultRef = useRef();
70672
70672
  const ref = props.ref || defaultRef;
70673
70673
  return jsxs("div", {
@@ -71138,7 +71138,7 @@ const findPreviousTableRow = currentRow => {
71138
71138
  return currentIndex > 0 ? allRows[currentIndex - 1] : null;
71139
71139
  };
71140
71140
 
71141
- installImportMetaCssBuild(import.meta);const css$h = /* css */`
71141
+ installImportMetaCssBuild(import.meta);const css$i = /* css */`
71142
71142
  @layer navi {
71143
71143
  .navi_table {
71144
71144
  --selection-border-color: var(--navi-selection-border-color, #0078d4);
@@ -71240,7 +71240,7 @@ const useTableSelectionController = ({
71240
71240
  onSelectionChange,
71241
71241
  selectionColor
71242
71242
  }) => {
71243
- import.meta.css = [css$h, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
71243
+ import.meta.css = [css$i, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
71244
71244
  const selectionController = useSelectionController({
71245
71245
  elementRef: tableRef,
71246
71246
  layout: "grid",
@@ -71711,7 +71711,7 @@ const useTableStickyContextValue = ({
71711
71711
  };
71712
71712
 
71713
71713
  installImportMetaCssBuild(import.meta);// TODO: sticky left/top frontier should likely use "followPosition"
71714
- const css$g = /* css */`
71714
+ const css$h = /* css */`
71715
71715
  @layer navi {
71716
71716
  .navi_table {
71717
71717
  --sticky-frontier-color: #c0c0c0;
@@ -71954,7 +71954,7 @@ const css$g = /* css */`
71954
71954
  const TableStickyFrontier = ({
71955
71955
  tableRef
71956
71956
  }) => {
71957
- import.meta.css = [css$g, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
71957
+ import.meta.css = [css$h, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
71958
71958
  const stickyLeftFrontierGhostRef = useRef();
71959
71959
  const stickyLeftFrontierPreviewRef = useRef();
71960
71960
  const stickyTopFrontierGhostRef = useRef();
@@ -72183,7 +72183,7 @@ const initMoveStickyFrontierViaPointer = (pointerdownEvent, {
72183
72183
  * inset 0 -1px 0 0 color; // Bottom border
72184
72184
  */
72185
72185
 
72186
- const css$f = /* css */ `
72186
+ const css$g = /* css */ `
72187
72187
  .navi_table_root {
72188
72188
  position: relative;
72189
72189
  max-width: var(--table-max-width, none);
@@ -72386,7 +72386,7 @@ const css$f = /* css */ `
72386
72386
  }
72387
72387
  `;
72388
72388
 
72389
- installImportMetaCssBuild(import.meta);const css$e = /* css */`
72389
+ installImportMetaCssBuild(import.meta);const css$f = /* css */`
72390
72390
  .navi_table_ui {
72391
72391
  position: fixed;
72392
72392
  inset: 0;
@@ -72397,7 +72397,7 @@ installImportMetaCssBuild(import.meta);const css$e = /* css */`
72397
72397
  }
72398
72398
  `;
72399
72399
  const TableUI = forwardRef((props, ref) => {
72400
- import.meta.css = [css$e, "@jsenv/navi/src/control/table/table_ui.jsx"];
72400
+ import.meta.css = [css$f, "@jsenv/navi/src/control/table/table_ui.jsx"];
72401
72401
  const {
72402
72402
  tableRef,
72403
72403
  tableId,
@@ -72503,7 +72503,7 @@ const RowIndexContext = createContext();
72503
72503
  const TableSectionContext = createContext();
72504
72504
  const useIsInTableHead = () => useContext(TableSectionContext) === "head";
72505
72505
  const Table = props => {
72506
- import.meta.css = [css$f, "@jsenv/navi/src/control/table/table.jsx"];
72506
+ import.meta.css = [css$g, "@jsenv/navi/src/control/table/table.jsx"];
72507
72507
  const tableDefaultRef = useRef();
72508
72508
  const tableDefaultId = `table-${useId()}`;
72509
72509
  const {
@@ -73331,7 +73331,7 @@ const normalizeKey = (key) => {
73331
73331
  return key;
73332
73332
  };
73333
73333
 
73334
- installImportMetaCssBuild(import.meta);const css$d = /* css */`
73334
+ installImportMetaCssBuild(import.meta);const css$e = /* css */`
73335
73335
  .navi_shortcut_container[data-visually-hidden] {
73336
73336
  /* Visually hidden container - doesn't affect layout */
73337
73337
  position: absolute;
@@ -73369,7 +73369,7 @@ installImportMetaCssBuild(import.meta);const css$d = /* css */`
73369
73369
  const ActiveKeyboardShortcuts = ({
73370
73370
  visible
73371
73371
  }) => {
73372
- import.meta.css = [css$d, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
73372
+ import.meta.css = [css$e, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
73373
73373
  const activeShortcuts = activeShortcutsSignal.value;
73374
73374
  return jsx("div", {
73375
73375
  className: "navi_shortcut_container",
@@ -73408,7 +73408,7 @@ const KeyboardShortcutAriaElement = ({
73408
73408
  });
73409
73409
  };
73410
73410
 
73411
- installImportMetaCssBuild(import.meta);const css$c = /* css */`
73411
+ installImportMetaCssBuild(import.meta);const css$d = /* css */`
73412
73412
  @layer navi {
73413
73413
  .navi_clipboard_container {
73414
73414
  --height: 1.5em;
@@ -73440,7 +73440,7 @@ const ButtonCopyToClipboard = ({
73440
73440
  children,
73441
73441
  ...props
73442
73442
  }) => {
73443
- import.meta.css = [css$c, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
73443
+ import.meta.css = [css$d, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
73444
73444
  const [copied, setCopied] = useState(false);
73445
73445
  const renderedRef = useRef();
73446
73446
  useEffect(() => {
@@ -73525,7 +73525,7 @@ const formatNumber = (value, { lang = languagesSignal.value } = {}) => {
73525
73525
  return new Intl.NumberFormat(lang).format(value);
73526
73526
  };
73527
73527
 
73528
- installImportMetaCssBuild(import.meta);const css$b = /* css */`
73528
+ installImportMetaCssBuild(import.meta);const css$c = /* css */`
73529
73529
  @layer navi {
73530
73530
  }
73531
73531
  .navi_text.navi_badge_count {
@@ -73690,7 +73690,7 @@ const BadgeCount = ({
73690
73690
  lineLayout,
73691
73691
  ...props
73692
73692
  }) => {
73693
- import.meta.css = [css$b, "@jsenv/navi/src/text/badge_count.jsx"];
73693
+ import.meta.css = [css$c, "@jsenv/navi/src/text/badge_count.jsx"];
73694
73694
  const defaultRef = useRef();
73695
73695
  props.ref = props.ref || defaultRef;
73696
73696
  const {
@@ -73832,7 +73832,7 @@ const BadgeCountCircle = ({
73832
73832
  });
73833
73833
  };
73834
73834
 
73835
- installImportMetaCssBuild(import.meta);const css$a = /* css */`
73835
+ installImportMetaCssBuild(import.meta);const css$b = /* css */`
73836
73836
  @layer navi {
73837
73837
  .navi_caption {
73838
73838
  --color: #6b7280;
@@ -73853,7 +73853,7 @@ const Caption = ({
73853
73853
  className,
73854
73854
  ...rest
73855
73855
  }) => {
73856
- import.meta.css = [css$a, "@jsenv/navi/src/text/caption.jsx"];
73856
+ import.meta.css = [css$b, "@jsenv/navi/src/text/caption.jsx"];
73857
73857
  return jsx(Text, {
73858
73858
  as: "small",
73859
73859
  size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
@@ -74266,7 +74266,7 @@ const WarningSvg = () => {
74266
74266
  });
74267
74267
  };
74268
74268
 
74269
- installImportMetaCssBuild(import.meta);const css$9 = /* css */`
74269
+ installImportMetaCssBuild(import.meta);const css$a = /* css */`
74270
74270
  @layer navi {
74271
74271
  .navi_message_box {
74272
74272
  --background-color-info: var(--navi-info-color-light);
@@ -74323,7 +74323,7 @@ const MessageBox = ({
74323
74323
  onClose,
74324
74324
  ...rest
74325
74325
  }) => {
74326
- import.meta.css = [css$9, "@jsenv/navi/src/text/message_box.jsx"];
74326
+ import.meta.css = [css$a, "@jsenv/navi/src/text/message_box.jsx"];
74327
74327
  const [hasTitleChild, setHasTitleChild] = useState(false);
74328
74328
  const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
74329
74329
  if (icon === true) {
@@ -74386,7 +74386,7 @@ const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success",
74386
74386
  const MessageBoxStatusContext = createContext();
74387
74387
  const MessageBoxReportTitleChildContext = createContext();
74388
74388
 
74389
- installImportMetaCssBuild(import.meta);const css$8 = /* css */`
74389
+ installImportMetaCssBuild(import.meta);const css$9 = /* css */`
74390
74390
  @layer navi {
74391
74391
  }
74392
74392
 
@@ -74477,7 +74477,7 @@ const Quantity = ({
74477
74477
  bold = true,
74478
74478
  ...props
74479
74479
  }) => {
74480
- import.meta.css = [css$8, "@jsenv/navi/src/text/quantity.jsx"];
74480
+ import.meta.css = [css$9, "@jsenv/navi/src/text/quantity.jsx"];
74481
74481
  const value = parseQuantityValue(children);
74482
74482
  const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
74483
74483
  const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
@@ -74535,7 +74535,7 @@ const parseQuantityValue = children => {
74535
74535
  return Number.isNaN(parsed) ? children : parsed;
74536
74536
  };
74537
74537
 
74538
- installImportMetaCssBuild(import.meta);const css$7 = /* css */`
74538
+ installImportMetaCssBuild(import.meta);const css$8 = /* css */`
74539
74539
  @layer navi {
74540
74540
  .navi_meter {
74541
74541
  --loader-color: var(--navi-loader-color);
@@ -74673,7 +74673,7 @@ const Meter = ({
74673
74673
  style,
74674
74674
  ...rest
74675
74675
  }) => {
74676
- import.meta.css = [css$7, "@jsenv/navi/src/text/meter.jsx"];
74676
+ import.meta.css = [css$8, "@jsenv/navi/src/text/meter.jsx"];
74677
74677
  const defaultRef = useRef();
74678
74678
  const ref = rest.ref || defaultRef;
74679
74679
  value = Number(value);
@@ -74798,7 +74798,7 @@ const Paragraph = props => {
74798
74798
  });
74799
74799
  };
74800
74800
 
74801
- installImportMetaCssBuild(import.meta);const css$6 = /* css */`
74801
+ installImportMetaCssBuild(import.meta);const css$7 = /* css */`
74802
74802
  .navi_text_box {
74803
74803
  min-width: 0;
74804
74804
  align-items: flex-start;
@@ -74840,7 +74840,7 @@ const TextBox = ({
74840
74840
  children,
74841
74841
  ...rest
74842
74842
  }) => {
74843
- import.meta.css = [css$6, "@jsenv/navi/src/text/text_box.jsx"];
74843
+ import.meta.css = [css$7, "@jsenv/navi/src/text/text_box.jsx"];
74844
74844
  const boxRef = useRef(null);
74845
74845
  const contentRef = useRef(null);
74846
74846
  useLayoutEffect(() => {
@@ -74886,7 +74886,7 @@ const adjustWidth = (boxEl, contentEl) => {
74886
74886
  contentEl.style.width = `${Math.ceil(optimalWidth)}px`;
74887
74887
  };
74888
74888
 
74889
- installImportMetaCssBuild(import.meta);const css$5 = /* css */`
74889
+ installImportMetaCssBuild(import.meta);const css$6 = /* css */`
74890
74890
  .navi_message_box {
74891
74891
  .navi_title {
74892
74892
  margin-top: 0;
@@ -74896,7 +74896,7 @@ installImportMetaCssBuild(import.meta);const css$5 = /* css */`
74896
74896
  }
74897
74897
  `;
74898
74898
  const Title = props => {
74899
- import.meta.css = [css$5, "@jsenv/navi/src/text/title.jsx"];
74899
+ import.meta.css = [css$6, "@jsenv/navi/src/text/title.jsx"];
74900
74900
  const messageBoxStatus = useContext(MessageBoxStatusContext);
74901
74901
  const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
74902
74902
  const titleLevel = parseInt(innerAs.slice(1));
@@ -74920,7 +74920,7 @@ const useTitleLevel = () => {
74920
74920
  };
74921
74921
  const TitlePseudoClasses = [":hover"];
74922
74922
 
74923
- installImportMetaCssBuild(import.meta);const css$4 = /* css */`
74923
+ installImportMetaCssBuild(import.meta);const css$5 = /* css */`
74924
74924
  @keyframes navi_image_shimmer {
74925
74925
  0% {
74926
74926
  background-position: -200% 0;
@@ -74975,7 +74975,7 @@ const Image = ({
74975
74975
  placeholderDark = false,
74976
74976
  ...rest
74977
74977
  }) => {
74978
- import.meta.css = [css$4, "@jsenv/navi/src/graphic/image.jsx"];
74978
+ import.meta.css = [css$5, "@jsenv/navi/src/graphic/image.jsx"];
74979
74979
  const loadedRef = useRef();
74980
74980
  let resolvedPlaceholder = placeholderColor;
74981
74981
  if (resolvedPlaceholder === undefined) {
@@ -75041,7 +75041,7 @@ installImportMetaCssBuild(import.meta);/**
75041
75041
  * @param {ReactNode[]} props.children - SVG elements (first is base, rest are overlays)
75042
75042
  * @returns {ReactElement} A composed SVG with all elements properly masked
75043
75043
  */
75044
- const css$3 = /* css */`
75044
+ const css$4 = /* css */`
75045
75045
  .svg_mask_content * {
75046
75046
  color: black !important;
75047
75047
  opacity: 1 !important;
@@ -75055,7 +75055,7 @@ const SVGMaskOverlay = ({
75055
75055
  viewBox,
75056
75056
  children
75057
75057
  }) => {
75058
- import.meta.css = [css$3, "@jsenv/navi/src/graphic/svg_mask_overlay.jsx"];
75058
+ import.meta.css = [css$4, "@jsenv/navi/src/graphic/svg_mask_overlay.jsx"];
75059
75059
  if (!Array.isArray(children)) {
75060
75060
  return children;
75061
75061
  }
@@ -75119,7 +75119,7 @@ installImportMetaCssBuild(import.meta);/**
75119
75119
  * space the outer box genuinely occupies — so a narrow window shrinks the card
75120
75120
  * and still shows that room, instead of pushing it against the edges.
75121
75121
  */
75122
- const css$2 = /* css */`
75122
+ const css$3 = /* css */`
75123
75123
  @layer navi {
75124
75124
  .navi_card_layout {
75125
75125
  --layout-margin: 30px;
@@ -75225,7 +75225,7 @@ const CardLayout = ({
75225
75225
  alignY = "center",
75226
75226
  ...props
75227
75227
  }) => {
75228
- import.meta.css = [css$2, "@jsenv/navi/src/layout/card_layout.jsx"];
75228
+ import.meta.css = [css$3, "@jsenv/navi/src/layout/card_layout.jsx"];
75229
75229
  return jsx(Box, {
75230
75230
  baseClassName: "navi_card_layout",
75231
75231
  styleCSSVars: CardLayoutStyleCSSVars,
@@ -75241,6 +75241,361 @@ const CardLayout = ({
75241
75241
  });
75242
75242
  };
75243
75243
 
75244
+ installImportMetaCssBuild(import.meta);/**
75245
+ * Where one stands in a walk of steps, drawn as dots on a path.
75246
+ *
75247
+ * Two distinct facts, drawn separately — they usually agree, and everything
75248
+ * this component says comes from the moments they do not:
75249
+ *
75250
+ * - the PATH (`reached`): how far the steps are answered without a gap. A
75251
+ * solid line runs from the first dot to the step it names, and those dots
75252
+ * are filled; past it the line is dashed — the road not walked yet. It
75253
+ * moves when a step is answered, not when one merely looks around.
75254
+ * - the POSITION (`current`): the step being looked at, marked by a halo
75255
+ * around its dot and its label emphasized. It travels freely, so it can be
75256
+ * AHEAD of the path (browsing step 3 while step 1 still misses an answer)
75257
+ * or BEHIND it (back on step 1 to change something already answered).
75258
+ *
75259
+ * Both move smoothly on change (a CSS transition each), so pressing a step
75260
+ * or answering one is seen travelling rather than jumping.
75261
+ *
75262
+ * The dots are drawn in SVG, twice: a muted layer, and a filled layer
75263
+ * clipped at the path's edge — the clip is what makes the path's progress a
75264
+ * single sweep that fills the line and the dots it crosses in one movement.
75265
+ * The line is drawn as segments between the dots (never behind them), so the
75266
+ * dots need no background of their own and the component sits on any
75267
+ * surface. Colors are CSS custom properties (see the css below), overridden
75268
+ * from outside for a dark band or a different accent.
75269
+ *
75270
+ * The steps are the CHILDREN — <StepList.Item value="club">Club</StepList.Item>
75271
+ * — read off the vnodes (toChildArray, so a .map() or a fragment is fine; a
75272
+ * component of your own wrapping an Item is not seen). The Item renders its
75273
+ * label; everything positional is this component's business.
75274
+ */
75275
+ const css$2 = /* css */`
75276
+ .navi_step_list {
75277
+ /* The knobs, in one place: accent is the path, muted is what the path
75278
+ has not reached, on-accent writes on filled dots. --step-list-path-line
75279
+ exists apart from the accent for a dark band where the walked line
75280
+ reads better plain white. */
75281
+ --step-list-accent: #4f8ef7;
75282
+ --step-list-on-accent: white;
75283
+ --step-list-muted: light-dark(#8a93a8, #8b99b8);
75284
+ --step-list-line: light-dark(#c9d0dd, rgba(255, 255, 255, 0.35));
75285
+ --step-list-current-color: light-dark(#1c2433, white);
75286
+ --step-list-path-line: var(--step-list-accent);
75287
+
75288
+ position: relative;
75289
+ display: block;
75290
+ height: 64px;
75291
+ }
75292
+ .navi_step_list_rail {
75293
+ position: absolute;
75294
+ top: 0;
75295
+ left: 0;
75296
+ pointer-events: none;
75297
+ }
75298
+ /* The road not walked yet. */
75299
+ .navi_step_list_rail line {
75300
+ stroke: var(--step-list-line);
75301
+ stroke-width: 2;
75302
+ stroke-dasharray: 4 5;
75303
+ }
75304
+ .navi_step_list_rail circle {
75305
+ fill: none;
75306
+ stroke: var(--step-list-muted);
75307
+ stroke-width: 1.5;
75308
+ }
75309
+ .navi_step_list_rail text {
75310
+ font-weight: 600;
75311
+ font-size: 12px;
75312
+ fill: var(--step-list-muted);
75313
+ }
75314
+ /* The path: same drawing, filled, revealed up to the step it has come to.
75315
+ The clip is set inline (a width in px); transitioning it is what makes
75316
+ an answered step SWEEP the line and the next dot rather than pop. */
75317
+ .navi_step_list_rail_filled {
75318
+ transition: clip-path 300ms ease;
75319
+ }
75320
+ .navi_step_list_rail_filled line {
75321
+ stroke: var(--step-list-path-line);
75322
+ stroke-dasharray: none;
75323
+ }
75324
+ .navi_step_list_rail_filled circle {
75325
+ fill: var(--step-list-accent);
75326
+ stroke: var(--step-list-accent);
75327
+ }
75328
+ .navi_step_list_rail_filled text {
75329
+ fill: var(--step-list-on-accent);
75330
+ }
75331
+ /* The position: a halo around the dot being looked at. It slides from dot
75332
+ to dot (transform, transitioned) — the g moves, the circle inside is
75333
+ drawn at x=0. */
75334
+ .navi_step_list_marker {
75335
+ transition: transform 300ms ease;
75336
+ }
75337
+ .navi_step_list_marker circle {
75338
+ fill: none;
75339
+ stroke: color-mix(in srgb, var(--step-list-accent) 65%, transparent);
75340
+ stroke-width: 1.5;
75341
+ }
75342
+ /* One press target per step, covering the dot AND the label under it. The
75343
+ feedback is NOT the whole surface: a rectangle would say the whole band
75344
+ is a button, when the affordance is the dot — so hover and focus land on
75345
+ a circle drawn over the dot (::before), plus the label brightening.
75346
+ --step-dot-x anchors both on the dot, wherever the dot sits in the slot:
75347
+ the first and last slots are asymmetric (cut at the container's edge,
75348
+ see the geometry in the component). */
75349
+ .navi_step_list_slot {
75350
+ position: absolute;
75351
+ top: 0;
75352
+ box-sizing: border-box;
75353
+ height: 100%;
75354
+ }
75355
+ /* Doubled selector: the discrete variant declares its own hover background
75356
+ var, and navi's stylesheet is injected after this one — specificity is
75357
+ what makes these values the ones read. */
75358
+ .navi_step_list .navi_step_list_step {
75359
+ position: relative;
75360
+ display: block;
75361
+ width: 100%;
75362
+ height: 100%;
75363
+ padding: 0;
75364
+ font-size: 12px;
75365
+ outline: none;
75366
+ --button-color: var(--step-list-muted);
75367
+ --button-color-readonly: var(--step-list-muted);
75368
+ --button-background-color: transparent;
75369
+ --button-background-color-hover: transparent;
75370
+ --button-background-color-readonly: transparent;
75371
+ }
75372
+ /* Centered on the dot: same vertical middle as the rail (top 0, height 34,
75373
+ cy 17). */
75374
+ .navi_step_list_step::before {
75375
+ position: absolute;
75376
+ top: 17px;
75377
+ left: var(--step-dot-x);
75378
+ width: 30px;
75379
+ height: 30px;
75380
+ border-radius: 50%;
75381
+ translate: -50% -50%;
75382
+ content: "";
75383
+ }
75384
+ .navi_step_list_step:hover::before,
75385
+ .navi_step_list_step[data-hover]::before {
75386
+ background: color-mix(in srgb, var(--step-list-accent) 15%, transparent);
75387
+ }
75388
+ .navi_step_list .navi_step_list_step:hover,
75389
+ .navi_step_list .navi_step_list_step[data-hover] {
75390
+ --button-color: var(--step-list-current-color);
75391
+ }
75392
+ .navi_step_list_step:focus-visible::before,
75393
+ .navi_step_list_step[data-focus-visible]::before {
75394
+ outline-width: var(--navi-focus-outline-width);
75395
+ outline-style: solid;
75396
+ outline-color: var(--navi-focus-outline-color);
75397
+ outline-offset: 1px;
75398
+ }
75399
+ .navi_step_list_label {
75400
+ position: absolute;
75401
+ bottom: 6px;
75402
+ left: var(--step-dot-x);
75403
+ white-space: nowrap;
75404
+ translate: -50% 0;
75405
+ }
75406
+ .navi_step_list .navi_step_list_step[data-current] {
75407
+ font-weight: 600;
75408
+ --button-color: var(--step-list-current-color);
75409
+ --button-color-readonly: var(--step-list-current-color);
75410
+ }
75411
+ `;
75412
+ const RAIL_H = 34;
75413
+ const DOT_R = 11;
75414
+ const RING_R = 14.5;
75415
+ // Room for the first and last dot (and their halo) not to touch the edges.
75416
+ const EDGE_INSET = 30;
75417
+ // Between a dot's edge and the line running to the next one: enough for the
75418
+ // halo of a current dot not to sit on the line.
75419
+ const LINE_GAP = 5;
75420
+
75421
+ /**
75422
+ * @type {import("ignore:preact").FunctionComponent<{
75423
+ * current?: string,
75424
+ * reached?: string,
75425
+ * onStepPress?: (value: string, event: Event) => void,
75426
+ * [key: string]: any,
75427
+ * }>}
75428
+ * @param {string} [current] - the step being looked at: its dot gets the
75429
+ * halo, its label the emphasis. Omit for "nowhere" — a confirmation
75430
+ * screen after the walk, say.
75431
+ * @param {string} [reached] - the step the path has come to: the line is
75432
+ * solid and the dots filled up to it, dashed past it. Omit for a path
75433
+ * that has not started.
75434
+ * @param {(value: string, event: Event) => void} [onStepPress] - a step was
75435
+ * pressed. Without it the steps are read-only — shown, not offered.
75436
+ */
75437
+ const StepList = ({
75438
+ current,
75439
+ reached,
75440
+ onStepPress,
75441
+ children,
75442
+ ...rest
75443
+ }) => {
75444
+ import.meta.css = [css$2, "@jsenv/navi/src/layout/step_list.jsx"];
75445
+ const rootRef = useRef();
75446
+ // The dots spread over whatever width the component is given, so the
75447
+ // geometry is measured rather than declared — and measured again when the
75448
+ // room changes.
75449
+ const [width, setWidth] = useState(0);
75450
+ useLayoutEffect(() => {
75451
+ const rootElement = rootRef.current;
75452
+ const measure = () => {
75453
+ setWidth(rootElement.clientWidth);
75454
+ };
75455
+ measure();
75456
+ const observer = new ResizeObserver(measure);
75457
+ observer.observe(rootElement);
75458
+ return () => {
75459
+ observer.disconnect();
75460
+ };
75461
+ }, []);
75462
+
75463
+ // The steps, read off the children: each <StepList.Item> vnode says which
75464
+ // step it is (value) and is rendered as the label under its dot.
75465
+ const stepVNodes = toChildArray(children).filter(child => child && child.props);
75466
+ const stepCount = stepVNodes.length;
75467
+ const valueOf = (vnode, index) => vnode.props.value ?? String(index);
75468
+ const dotXs = [];
75469
+ if (width > 0 && stepCount > 0) {
75470
+ const span = width - EDGE_INSET * 2;
75471
+ let index = 0;
75472
+ while (index < stepCount) {
75473
+ dotXs.push(stepCount === 1 ? width / 2 : EDGE_INSET + span * index / (stepCount - 1));
75474
+ index++;
75475
+ }
75476
+ }
75477
+ const indexOf = value => stepVNodes.findIndex((vnode, index) => valueOf(vnode, index) === value);
75478
+ const currentIndex = current === undefined ? -1 : indexOf(current);
75479
+ const reachedIndex = reached === undefined ? -1 : indexOf(reached);
75480
+ // Covers the reached dot entirely (radius plus stroke), and nothing when
75481
+ // the path has not started.
75482
+ const fillX = reachedIndex === -1 ? 0 : dotXs[reachedIndex] + DOT_R + 3;
75483
+ const cy = RAIL_H / 2;
75484
+ const slotWidth = dotXs.length > 1 ? dotXs[1] - dotXs[0] : width;
75485
+ const renderRail = filled => jsx("svg", {
75486
+ className: filled ? "navi_step_list_rail navi_step_list_rail_filled" : "navi_step_list_rail",
75487
+ style: filled ? {
75488
+ clipPath: `inset(0 ${width - fillX}px 0 0)`
75489
+ } : undefined,
75490
+ width: width,
75491
+ height: RAIL_H,
75492
+ viewBox: `0 0 ${width} ${RAIL_H}`,
75493
+ "aria-hidden": "true",
75494
+ children: dotXs.map((x, index) => jsxs("g", {
75495
+ children: [index > 0 ? jsx("line", {
75496
+ x1: dotXs[index - 1] + DOT_R + LINE_GAP,
75497
+ y1: cy,
75498
+ x2: x - DOT_R - LINE_GAP,
75499
+ y2: cy
75500
+ }) : null, jsx("circle", {
75501
+ cx: x,
75502
+ cy: cy,
75503
+ r: DOT_R
75504
+ }), jsx("text", {
75505
+ x: x,
75506
+ y: cy,
75507
+ dy: "0.36em",
75508
+ "text-anchor": "middle",
75509
+ children: index + 1
75510
+ })]
75511
+ }, valueOf(stepVNodes[index], index)))
75512
+ });
75513
+ return jsx(Box, {
75514
+ ...rest,
75515
+ ref: rootRef,
75516
+ baseClassName: "navi_step_list",
75517
+ "data-step-list": "",
75518
+ children: width > 0 && stepCount > 0 ? jsxs(Fragment$1, {
75519
+ children: [renderRail(false), renderRail(true), currentIndex !== -1 && dotXs[currentIndex] !== undefined ? jsx("svg", {
75520
+ className: "navi_step_list_rail",
75521
+ width: width,
75522
+ height: RAIL_H,
75523
+ viewBox: `0 0 ${width} ${RAIL_H}`,
75524
+ "aria-hidden": "true",
75525
+ children: jsx("g", {
75526
+ className: "navi_step_list_marker",
75527
+ style: {
75528
+ transform: `translateX(${dotXs[currentIndex]}px)`
75529
+ },
75530
+ children: jsx("circle", {
75531
+ cx: "0",
75532
+ cy: cy,
75533
+ r: RING_R
75534
+ })
75535
+ })
75536
+ }) : null, stepVNodes.map((stepVNode, index) => {
75537
+ const value = valueOf(stepVNode, index);
75538
+ // Whatever else the Item was given reaches its button — a
75539
+ // pseudoState held for a demo, an aria attribute.
75540
+ const itemRest = {
75541
+ ...stepVNode.props
75542
+ };
75543
+ delete itemRest.value;
75544
+ delete itemRest.children;
75545
+ // The slots tile the row, cut at the container's edges: the
75546
+ // first and the last cover only the inner half of the room an
75547
+ // interior slot gets, so pressing just outside the box presses
75548
+ // nothing.
75549
+ const first = index === 0;
75550
+ const last = index === stepCount - 1;
75551
+ const slotLeft = first ? dotXs[index] - EDGE_INSET : dotXs[index] - slotWidth / 2;
75552
+ const slotRight = last ? dotXs[index] + EDGE_INSET : dotXs[index] + slotWidth / 2;
75553
+ return jsx("div", {
75554
+ className: "navi_step_list_slot",
75555
+ style: {
75556
+ "left": `${slotLeft}px`,
75557
+ "width": `${slotRight - slotLeft}px`,
75558
+ "--step-dot-x": `${dotXs[index] - slotLeft}px`
75559
+ },
75560
+ children: jsx(Button, {
75561
+ ...itemRest,
75562
+ variant: "discrete",
75563
+ className: "navi_step_list_step",
75564
+ "aria-current": index === currentIndex ? "step" : undefined,
75565
+ "data-current": index === currentIndex ? "" : undefined,
75566
+ readOnly: !onStepPress,
75567
+ onClick: onStepPress ? e => {
75568
+ onStepPress(value, e);
75569
+ } : undefined,
75570
+ children: jsx("span", {
75571
+ className: "navi_step_list_label",
75572
+ children: stepVNode
75573
+ })
75574
+ })
75575
+ }, value);
75576
+ })]
75577
+ }) : null
75578
+ });
75579
+ };
75580
+
75581
+ /**
75582
+ * One step of the walk: `value` names it (what `current`/`reached` say and
75583
+ * what a press reports), the children are its label. Rendered under its dot;
75584
+ * where the dot is, and what state it shows, is the StepList's business.
75585
+ *
75586
+ * It is both StepList.Item and an export of its own, the way Slide is to
75587
+ * SlideContainer.
75588
+ *
75589
+ * @type {import("ignore:preact").FunctionComponent<{
75590
+ * value: string,
75591
+ * [key: string]: any,
75592
+ * }>}
75593
+ */
75594
+ const Step = ({
75595
+ children
75596
+ }) => children;
75597
+ StepList.Item = Step;
75598
+
75244
75599
  installImportMetaCssBuild(import.meta);const css$1 = /* css */`
75245
75600
  @layer navi {
75246
75601
  .navi_viewport_layout {
@@ -75815,5 +76170,5 @@ const UserSvg = () => jsx("svg", {
75815
76170
  })
75816
76171
  });
75817
76172
 
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 };
76173
+ 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
76174
  //# sourceMappingURL=jsenv_navi.js.map