@jsenv/navi 0.26.20 → 0.26.22

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.
@@ -6612,6 +6612,7 @@ const VISUAL_PROPS = {
6612
6612
  overflowWrap: "normal",
6613
6613
  };
6614
6614
  },
6615
+ objectFit: PASS_THROUGH,
6615
6616
  accentColor: PASS_THROUGH,
6616
6617
  };
6617
6618
  const CONTENT_PROPS = {
@@ -16303,7 +16304,7 @@ installImportMetaCssBuild(import.meta);
16303
16304
  * - Centers in viewport when no anchor element provided or anchor is too big
16304
16305
  */
16305
16306
 
16306
- const css$B = /* css */`
16307
+ const css$E = /* css */`
16307
16308
  @layer navi {
16308
16309
  .navi_callout {
16309
16310
  --callout-success-color: #4caf50;
@@ -16477,7 +16478,7 @@ const openCallout = (message, {
16477
16478
  showErrorStack,
16478
16479
  debug = false
16479
16480
  } = {}) => {
16480
- import.meta.css = [css$B, "@jsenv/navi/src/field/validation/callout/callout.js"];
16481
+ import.meta.css = [css$E, "@jsenv/navi/src/field/validation/callout/callout.js"];
16481
16482
  const callout = {
16482
16483
  opened: true,
16483
16484
  close: null,
@@ -19603,55 +19604,57 @@ const setupNetworkMonitoring = () => {
19603
19604
  };
19604
19605
  setupNetworkMonitoring();
19605
19606
 
19606
- installImportMetaCssBuild(import.meta);/**
19607
- * RectangleLoading Component
19608
- *
19609
- * A responsive loading indicator that dynamically adjusts to fit its container.
19610
- * Displays an animated outline with a traveling dot that follows the container's shape.
19611
- *
19612
- * Features:
19613
- * - Adapts to any container dimensions using ResizeObserver
19614
- * - Scales stroke width, margins and corner radius proportionally
19615
- * - Animates using native SVG animations for smooth performance
19616
- * - High-quality SVG rendering with proper path calculations
19617
- *
19618
- * @param {Object} props - Component props
19619
- * @param {string} [props.color="#383a36"] - Color of the loading indicator
19620
- * @param {number} [props.radius=0] - Corner radius of the rectangle (px)
19621
- */
19622
- import.meta.css = [/* css */`
19623
- .navi_rectangle_loading {
19607
+ installImportMetaCssBuild(import.meta);const css$D = /* css */`
19608
+ .navi_loading_indicator_fluid_container {
19624
19609
  position: relative;
19625
19610
  display: flex;
19626
19611
  width: 100%;
19627
19612
  height: 100%;
19628
- opacity: 0;
19629
- }
19630
-
19631
- .navi_rectangle_loading[data-visible] {
19613
+ border-radius: inherit;
19632
19614
  opacity: 1;
19615
+
19616
+ &[hidden] {
19617
+ display: flex;
19618
+ opacity: 0;
19619
+ }
19633
19620
  }
19634
- `, "@jsenv/navi/src/graphic/loader/rectangle_loading.jsx"];
19635
- const RectangleLoading = ({
19636
- shouldShowSpinner,
19621
+ `;
19622
+
19623
+ /**
19624
+ * A loading indicator that fills its container, adapting to its shape like water.
19625
+ * Reads border-radius from the container (or accepts an explicit `radius` prop).
19626
+ *
19627
+ * @param {string} [props.color="currentColor"] - Stroke color
19628
+ * @param {number|"inherit"} [props.radius] - Corner radius in px. When omitted, reads border-radius from the container.
19629
+ * @param {number} [props.size=2] - Stroke width in px
19630
+ */
19631
+ const LoadingIndicatorFluid = ({
19637
19632
  color = "currentColor",
19638
- radius = 0,
19639
- size = 2
19633
+ size = 2,
19634
+ radius,
19635
+ ...rest
19640
19636
  }) => {
19641
- const containerRef = useRef(null);
19637
+ import.meta.css = [css$D, "@jsenv/navi/src/graphic/loading/loading_indicator_fluid.jsx"];
19638
+ const ref = useRef(null);
19639
+ // The container dimensions can be deduced from the ref itself as the indicator is absolute inset 0
19642
19640
  const [containerWidth, setContainerWidth] = useState(0);
19643
19641
  const [containerHeight, setContainerHeight] = useState(0);
19642
+ const [containerRadius, setContainerRadius] = useState(0);
19644
19643
  useLayoutEffect(() => {
19645
- const container = containerRef.current;
19646
- if (!container) {
19644
+ const indicatorEl = ref.current;
19645
+ if (!indicatorEl) {
19647
19646
  return null;
19648
19647
  }
19649
19648
  const {
19650
19649
  width,
19651
19650
  height
19652
- } = container.getBoundingClientRect();
19651
+ } = indicatorEl.getBoundingClientRect();
19653
19652
  setContainerWidth(width);
19654
19653
  setContainerHeight(height);
19654
+ if (radius === undefined || radius === "inherit") {
19655
+ const radius = getComputedStyle(indicatorEl).borderRadius;
19656
+ setContainerRadius(radius);
19657
+ }
19655
19658
  let animationFrameId = null;
19656
19659
  // Create a resize observer to detect changes in the container's dimensions
19657
19660
  const resizeObserver = new ResizeObserver(entries => {
@@ -19669,7 +19672,7 @@ const RectangleLoading = ({
19669
19672
  setContainerHeight(height);
19670
19673
  });
19671
19674
  });
19672
- resizeObserver.observe(container);
19675
+ resizeObserver.observe(indicatorEl);
19673
19676
  return () => {
19674
19677
  if (animationFrameId) {
19675
19678
  cancelAnimationFrame(animationFrameId);
@@ -19678,19 +19681,19 @@ const RectangleLoading = ({
19678
19681
  };
19679
19682
  }, []);
19680
19683
  return jsx("span", {
19681
- ref: containerRef,
19682
- className: "navi_rectangle_loading",
19683
- "data-visible": shouldShowSpinner ? "" : undefined,
19684
- children: containerWidth > 0 && containerHeight > 0 && jsx(RectangleLoadingSvg, {
19685
- radius: radius,
19684
+ ...rest,
19685
+ ref: ref,
19686
+ className: "navi_loading_indicator_fluid_container",
19687
+ children: containerWidth > 0 && containerHeight > 0 && jsx(LoadingRectangleSvg, {
19686
19688
  color: color,
19689
+ radius: containerRadius,
19687
19690
  width: containerWidth,
19688
19691
  height: containerHeight,
19689
19692
  strokeWidth: size
19690
19693
  })
19691
19694
  });
19692
19695
  };
19693
- const RectangleLoadingSvg = ({
19696
+ const LoadingRectangleSvg = ({
19694
19697
  width,
19695
19698
  height,
19696
19699
  color,
@@ -19772,6 +19775,7 @@ const RectangleLoadingSvg = ({
19772
19775
  style: "overflow: visible",
19773
19776
  xmlns: "http://www.w3.org/2000/svg",
19774
19777
  "shape-rendering": "geometricPrecision",
19778
+ "data-radius": radius,
19775
19779
  children: [isCircle ? jsx("circle", {
19776
19780
  cx: margin + drawableWidth / 2,
19777
19781
  cy: margin + drawableHeight / 2,
@@ -19818,178 +19822,149 @@ const RectangleLoadingSvg = ({
19818
19822
  });
19819
19823
  };
19820
19824
 
19821
- installImportMetaCssBuild(import.meta);import.meta.css = [/* css */`
19822
- .navi_loading_rectangle_wrapper {
19825
+ installImportMetaCssBuild(import.meta);const css$C = /* css */`
19826
+ .navi_loading_outline_wrapper {
19823
19827
  position: absolute;
19824
- top: var(--rectangle-top, 0);
19825
- right: var(--rectangle-right, 0);
19826
- bottom: var(--rectangle-bottom, 0);
19827
- left: var(--rectangle-left, 0);
19828
+ top: var(--loading-rectangle-top, 0);
19829
+ right: var(--loading-rectangle-right, 0);
19830
+ bottom: var(--loading-rectangle-bottom, 0);
19831
+ left: var(--loading-rectangle-left, 0);
19828
19832
  z-index: 1;
19829
- opacity: 0;
19833
+ border-radius: inherit;
19830
19834
  pointer-events: none;
19831
19835
 
19832
- &[data-visible] {
19833
- opacity: 1;
19836
+ &[hidden] {
19837
+ display: block;
19838
+ opacity: 0;
19834
19839
  }
19835
19840
  }
19836
- `, "@jsenv/navi/src/graphic/loader/loader_background.jsx"];
19837
- const LoaderBackground = ({
19838
- loading,
19839
- containerRef,
19840
- targetSelector,
19841
- color,
19842
- inset = 0,
19843
- borderRadius = 0,
19844
- spacingTop = 0,
19845
- spacingLeft = 0,
19846
- spacingBottom = 0,
19847
- spacingRight = 0,
19848
- children
19849
- }) => {
19850
- if (containerRef) {
19851
- const container = containerRef.current;
19841
+ `;
19842
+ const LoadingOutline = props => {
19843
+ import.meta.css = [css$C, "@jsenv/navi/src/graphic/loading/loading_outline.jsx"];
19844
+ if (props.containerRef) {
19845
+ const container = props.containerRef.current;
19852
19846
  if (!container) {
19853
- return children;
19847
+ return props.children;
19854
19848
  }
19855
- return createPortal(jsx(LoaderBackgroundWithPortal, {
19849
+ return createPortal(jsx(LoadingOutlineWithPortal, {
19856
19850
  container: container,
19857
- loading: loading,
19858
- color: color,
19859
- inset: inset,
19860
- spacingTop: spacingTop,
19861
- spacingLeft: spacingLeft,
19862
- spacingBottom: spacingBottom,
19863
- spacingRight: spacingRight,
19864
- children: children
19851
+ ...props,
19852
+ containerRef: undefined
19865
19853
  }), container);
19866
19854
  }
19867
- return jsx(LoaderBackgroundBasic, {
19868
- targetSelector: targetSelector,
19869
- loading: loading,
19870
- color: color,
19871
- inset: inset,
19872
- borderRadius: borderRadius,
19873
- spacingTop: spacingTop,
19874
- spacingLeft: spacingLeft,
19875
- spacingBottom: spacingBottom,
19876
- spacingRight: spacingRight,
19877
- children: children
19878
- });
19879
- };
19880
- const LoaderBackgroundWithPortal = ({
19881
- container,
19882
- loading,
19883
- color,
19884
- inset,
19885
- borderRadius,
19886
- spacingTop,
19887
- spacingLeft,
19888
- spacingBottom,
19889
- spacingRight,
19890
- children
19891
- }) => {
19892
- const shouldShowSpinner = useDebounceTrue(loading, 300);
19893
- if (!shouldShowSpinner) {
19894
- return children;
19895
- }
19896
- container.style.position = "relative";
19897
- let paddingTop = 0;
19898
- if (container.nodeName === "DETAILS") {
19899
- paddingTop = container.querySelector("summary").offsetHeight;
19900
- }
19901
- return jsxs(Fragment, {
19902
- children: [jsx("div", {
19903
- style: {
19904
- position: "absolute",
19905
- top: `${inset + paddingTop + spacingTop}px`,
19906
- bottom: `${inset + spacingBottom}px`,
19907
- left: `${inset + spacingLeft}px`,
19908
- right: `${inset + spacingRight}px`
19909
- },
19910
- children: shouldShowSpinner && jsx(RectangleLoading, {
19911
- color: color,
19912
- radius: borderRadius
19913
- })
19914
- }), children]
19855
+ return jsx(LoadingOutlineUI, {
19856
+ ...props
19915
19857
  });
19916
19858
  };
19917
- const LoaderBackgroundBasic = ({
19918
- loading,
19919
- targetSelector,
19920
- color,
19921
- borderWidth = 0,
19922
- borderRadius = 0,
19923
- spacingTop,
19924
- spacingLeft,
19925
- spacingBottom,
19926
- spacingRight,
19927
- marginTop = 0,
19928
- marginLeft = 0,
19929
- marginBottom = 0,
19930
- marginRight = 0,
19931
- paddingTop = 0,
19932
- paddingLeft = 0,
19933
- paddingBottom = 0,
19934
- paddingRight = 0,
19935
- inset,
19936
- children
19937
- }) => {
19859
+ const LoadingOutlineUI = props => {
19860
+ const {
19861
+ loading,
19862
+ targetSelector,
19863
+ color,
19864
+ borderWidth = 0,
19865
+ radius,
19866
+ spacingTop = 0,
19867
+ spacingRight = 0,
19868
+ spacingBottom = 0,
19869
+ spacingLeft = 0,
19870
+ marginTop = 0,
19871
+ marginRight = 0,
19872
+ marginBottom = 0,
19873
+ marginLeft = 0,
19874
+ paddingTop = 0,
19875
+ paddingRight = 0,
19876
+ paddingBottom = 0,
19877
+ paddingLeft = 0,
19878
+ inset = 0,
19879
+ children
19880
+ } = props;
19938
19881
  const shouldShowSpinner = useDebounceTrue(loading, 300);
19939
19882
  const rectangleRef = useRef(null);
19940
- spacingTop += inset;
19941
- // spacingTop += outlineOffset;
19942
- // spacingTop -= borderTopWidth;
19943
- spacingTop += marginTop;
19944
- spacingLeft += inset;
19945
- // spacingLeft += outlineOffset;
19946
- // spacingLeft -= borderLeftWidth;
19947
- spacingLeft += marginLeft;
19948
- spacingRight += inset;
19949
- // spacingRight += outlineOffset;
19950
- // spacingRight -= borderRightWidth;
19951
- spacingRight += marginRight;
19952
- spacingBottom += inset;
19953
- // spacingBottom += outlineOffset;
19954
- // spacingBottom -= borderBottomWidth;
19955
- spacingBottom += marginBottom;
19883
+ let insetTop = inset + spacingTop + marginTop;
19884
+ let insetRight = inset + spacingRight + marginRight;
19885
+ let insetBottom = inset + spacingBottom + marginBottom;
19886
+ let insetLeft = inset + spacingLeft + marginLeft;
19956
19887
  if (targetSelector) {
19957
19888
  // oversimplification that actually works
19958
19889
  // (simplified because it assumes the targeted element is a direct child of the contained element which may have padding)
19959
- spacingTop += paddingTop;
19960
- spacingLeft += paddingLeft;
19961
- spacingRight += paddingRight;
19962
- spacingBottom += paddingBottom;
19890
+ insetTop += paddingTop;
19891
+ insetRight += paddingBottom;
19892
+ insetBottom += paddingRight;
19893
+ insetLeft += paddingLeft;
19963
19894
  }
19964
19895
  const maxBorderWidth = Math.max(borderWidth);
19965
19896
  const halfMaxBorderSize = maxBorderWidth / 2;
19966
19897
  const size = halfMaxBorderSize < 2 ? 2 : halfMaxBorderSize;
19967
19898
  const lineHalfSize = size / 2;
19968
- spacingTop -= lineHalfSize;
19969
- spacingLeft -= lineHalfSize;
19970
- spacingRight -= lineHalfSize;
19971
- spacingBottom -= lineHalfSize;
19899
+ insetTop -= lineHalfSize;
19900
+ insetRight -= lineHalfSize;
19901
+ insetBottom -= lineHalfSize;
19902
+ insetLeft -= lineHalfSize;
19972
19903
  return jsxs(Fragment, {
19973
19904
  children: [jsx("span", {
19974
19905
  ref: rectangleRef,
19975
- className: "navi_loading_rectangle_wrapper",
19976
- "data-visible": shouldShowSpinner ? "" : undefined,
19906
+ className: "navi_loading_outline_wrapper",
19907
+ hidden: !shouldShowSpinner,
19977
19908
  style: {
19978
- "--rectangle-top": `${spacingTop}px`,
19979
- "--rectangle-left": `${spacingLeft}px`,
19980
- "--rectangle-bottom": `${spacingBottom}px`,
19981
- "--rectangle-right": `${spacingRight}px`
19909
+ "--loading-rectangle-top": `${insetTop}px`,
19910
+ "--loading-rectangle-right": `${insetRight}px`,
19911
+ "--loading-rectangle-bottom": `${insetBottom}px`,
19912
+ "--loading-rectangle-left": `${insetLeft}px`
19982
19913
  },
19983
- children: loading && jsx(RectangleLoading, {
19984
- shouldShowSpinner: shouldShowSpinner,
19914
+ children: loading && jsx(LoadingIndicatorFluid, {
19915
+ hidden: !shouldShowSpinner,
19916
+ radius: radius,
19985
19917
  color: color,
19986
- radius: borderRadius,
19987
19918
  size: size
19988
19919
  })
19989
19920
  }), children]
19990
19921
  });
19991
19922
  };
19992
19923
 
19924
+ // Not actually used anymore.
19925
+ // Now all UI have a common wrapper that can be used to display the loading indicator without needing a container portal.
19926
+ const LoadingOutlineWithPortal = props => {
19927
+ const {
19928
+ container,
19929
+ loading,
19930
+ color,
19931
+ inset = 0,
19932
+ radius,
19933
+ spacingTop = 0,
19934
+ spacingRight = 0,
19935
+ spacingBottom = 0,
19936
+ spacingLeft = 0,
19937
+ children
19938
+ } = props;
19939
+ const shouldShowSpinner = useDebounceTrue(loading, 300);
19940
+ if (!shouldShowSpinner) {
19941
+ return children;
19942
+ }
19943
+ container.style.position = "relative";
19944
+ let insetTop = inset + spacingTop;
19945
+ let insetRight = inset + spacingRight;
19946
+ let insetBottom = inset + spacingBottom;
19947
+ let insetLeft = inset + spacingLeft;
19948
+ if (container.nodeName === "DETAILS") {
19949
+ insetTop += container.querySelector("summary").offsetHeight;
19950
+ }
19951
+ return jsxs(Fragment, {
19952
+ children: [jsx("div", {
19953
+ className: "navi_loading_outline_wrapper",
19954
+ style: {
19955
+ "--loading-rectangle-top": `${insetTop}px`,
19956
+ "--loading-rectangle-right": `${insetRight}px`,
19957
+ "--loading-rectangle-bottom": `${insetBottom}px`,
19958
+ "--loading-rectangle-left": `${insetLeft}px`
19959
+ },
19960
+ children: shouldShowSpinner && jsx(LoadingIndicatorFluid, {
19961
+ color: color,
19962
+ radius: radius
19963
+ })
19964
+ }), children]
19965
+ });
19966
+ };
19967
+
19993
19968
  // used by form elements such as <input>, <select>, <textarea> to have their own action bound to a single parameter
19994
19969
  // when inside a <form> the form params are updated when the form element single param is updated
19995
19970
  const useActionBoundToOneParam = (action, externalValue) => {
@@ -20811,7 +20786,7 @@ const selectByTextStrings = (element, range, startText, endText) => {
20811
20786
  };
20812
20787
 
20813
20788
  installImportMetaCssBuild(import.meta);// https://jsfiddle.net/v5xzJ/4/
20814
- const css$A = /* css */`
20789
+ const css$B = /* css */`
20815
20790
  @layer navi {
20816
20791
  .navi_text {
20817
20792
  &[data-skeleton] {
@@ -21210,7 +21185,7 @@ const TextDispatcher = props => {
21210
21185
  });
21211
21186
  };
21212
21187
  const TextUI = props => {
21213
- import.meta.css = [css$A, "@jsenv/navi/src/text/text.jsx"];
21188
+ import.meta.css = [css$B, "@jsenv/navi/src/text/text.jsx"];
21214
21189
  let {
21215
21190
  ref,
21216
21191
  spacing,
@@ -21382,7 +21357,7 @@ const TextWithSelectRange = ({
21382
21357
  });
21383
21358
  };
21384
21359
 
21385
- installImportMetaCssBuild(import.meta);const css$z = /* css */`
21360
+ installImportMetaCssBuild(import.meta);const css$A = /* css */`
21386
21361
  .navi_text_anchor {
21387
21362
  vertical-align: baseline;
21388
21363
  user-select: none;
@@ -21417,7 +21392,7 @@ const TextAnchor = ({
21417
21392
  textSize,
21418
21393
  lineLayout
21419
21394
  }) => {
21420
- import.meta.css = [css$z, "@jsenv/navi/src/text/text_anchor.jsx"];
21395
+ import.meta.css = [css$A, "@jsenv/navi/src/text/text_anchor.jsx"];
21421
21396
  const anchorRef = useRef();
21422
21397
  const setTopOffset = (childEl, topOffset) => {
21423
21398
  // position:relative + top shifts the element visually.
@@ -21519,7 +21494,7 @@ const computeTopOffset = ({
21519
21494
  };
21520
21495
  const charTopCanvas = document.createElement("canvas");
21521
21496
 
21522
- installImportMetaCssBuild(import.meta);const css$y = /* css */`
21497
+ installImportMetaCssBuild(import.meta);const css$z = /* css */`
21523
21498
  @layer navi {
21524
21499
  /* Ensure data attributes from box.jsx can win to update display */
21525
21500
  .navi_icon {
@@ -21592,7 +21567,7 @@ const Icon = ({
21592
21567
  lineLayout,
21593
21568
  ...props
21594
21569
  }) => {
21595
- import.meta.css = [css$y, "@jsenv/navi/src/text/icon.jsx"];
21570
+ import.meta.css = [css$z, "@jsenv/navi/src/text/icon.jsx"];
21596
21571
  const innerChildren = href ? jsx("svg", {
21597
21572
  width: "100%",
21598
21573
  height: "100%",
@@ -22544,7 +22519,7 @@ const useUIState = (uiStateController) => {
22544
22519
  return trackedUIState;
22545
22520
  };
22546
22521
 
22547
- installImportMetaCssBuild(import.meta);const css$x = /* css */`
22522
+ installImportMetaCssBuild(import.meta);const css$y = /* css */`
22548
22523
  @layer navi {
22549
22524
  .navi_button {
22550
22525
  --button-border-radius: 2px;
@@ -22830,7 +22805,7 @@ const ButtonDispatcher = props => {
22830
22805
  });
22831
22806
  };
22832
22807
  const ButtonUI = props => {
22833
- import.meta.css = [css$x, "@jsenv/navi/src/field/button.jsx"];
22808
+ import.meta.css = [css$y, "@jsenv/navi/src/field/button.jsx"];
22834
22809
  const {
22835
22810
  ref,
22836
22811
  readOnly,
@@ -22930,7 +22905,7 @@ const ButtonUI = props => {
22930
22905
  },
22931
22906
  visualSelector: visualSelector,
22932
22907
  hasChildFunction: true,
22933
- children: [jsx(LoaderBackground, {
22908
+ children: [jsx(LoadingOutline, {
22934
22909
  loading: innerLoading,
22935
22910
  inset: -1,
22936
22911
  color: "var(--button-loader-color)"
@@ -23155,7 +23130,7 @@ const WarningSvg = () => {
23155
23130
  });
23156
23131
  };
23157
23132
 
23158
- installImportMetaCssBuild(import.meta);const css$w = /* css */`
23133
+ installImportMetaCssBuild(import.meta);const css$x = /* css */`
23159
23134
  @layer navi {
23160
23135
  .navi_message_box {
23161
23136
  --background-color-info: var(--navi-info-color-light);
@@ -23208,7 +23183,7 @@ const MessageBox = ({
23208
23183
  onClose,
23209
23184
  ...rest
23210
23185
  }) => {
23211
- import.meta.css = [css$w, "@jsenv/navi/src/text/message_box.jsx"];
23186
+ import.meta.css = [css$x, "@jsenv/navi/src/text/message_box.jsx"];
23212
23187
  const [hasTitleChild, setHasTitleChild] = useState(false);
23213
23188
  const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
23214
23189
  if (icon === true) {
@@ -23267,7 +23242,7 @@ const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success",
23267
23242
  const MessageBoxStatusContext = createContext();
23268
23243
  const MessageBoxReportTitleChildContext = createContext();
23269
23244
 
23270
- installImportMetaCssBuild(import.meta);const css$v = /* css */`
23245
+ installImportMetaCssBuild(import.meta);const css$w = /* css */`
23271
23246
  .navi_message_box {
23272
23247
  .navi_title {
23273
23248
  margin-top: 0;
@@ -23277,7 +23252,7 @@ installImportMetaCssBuild(import.meta);const css$v = /* css */`
23277
23252
  }
23278
23253
  `;
23279
23254
  const Title = props => {
23280
- import.meta.css = [css$v, "@jsenv/navi/src/text/title.jsx"];
23255
+ import.meta.css = [css$w, "@jsenv/navi/src/text/title.jsx"];
23281
23256
  const messageBoxStatus = useContext(MessageBoxStatusContext);
23282
23257
  const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
23283
23258
  const titleLevel = parseInt(innerAs.slice(1));
@@ -23355,7 +23330,7 @@ const useDimColorWhen = (elementRef, shouldDim) => {
23355
23330
  });
23356
23331
  };
23357
23332
 
23358
- installImportMetaCssBuild(import.meta);const css$u = /* css */`
23333
+ installImportMetaCssBuild(import.meta);const css$v = /* css */`
23359
23334
  @layer navi {
23360
23335
  .navi_link {
23361
23336
  --link-border-radius: unset;
@@ -23707,7 +23682,7 @@ Object.assign(PSEUDO_CLASSES, {
23707
23682
  }
23708
23683
  });
23709
23684
  const Link = props => {
23710
- import.meta.css = [css$u, "@jsenv/navi/src/nav/link/link.jsx"];
23685
+ import.meta.css = [css$v, "@jsenv/navi/src/nav/link/link.jsx"];
23711
23686
  return renderActionableComponent(props, {
23712
23687
  Basic: LinkBasic,
23713
23688
  WithAction: LinkWithAction
@@ -23908,7 +23883,7 @@ const LinkPlain = props => {
23908
23883
  onKeyDown?.(e);
23909
23884
  },
23910
23885
  childrenOutsideFlow: jsxs(Fragment, {
23911
- children: [jsx(LoaderBackground, {
23886
+ children: [jsx(LoadingOutline, {
23912
23887
  loading: loading,
23913
23888
  inset: 1,
23914
23889
  color: "var(--link-loader-color)"
@@ -23973,7 +23948,7 @@ installImportMetaCssBuild(import.meta);/**
23973
23948
  * TabList component with support for horizontal and vertical layouts
23974
23949
  * https://dribbble.com/search/tabs
23975
23950
  */
23976
- const css$t = /* css */`
23951
+ const css$u = /* css */`
23977
23952
  @layer navi {
23978
23953
  .navi_nav {
23979
23954
  --nav-border: none;
@@ -24109,7 +24084,7 @@ const Nav = ({
24109
24084
  panelBorderConnection,
24110
24085
  ...props
24111
24086
  }) => {
24112
- import.meta.css = [css$t, "@jsenv/navi/src/nav/link/nav.jsx"];
24087
+ import.meta.css = [css$u, "@jsenv/navi/src/nav/link/nav.jsx"];
24113
24088
  children = toChildArray(children);
24114
24089
  return jsx(Box, {
24115
24090
  as: "nav",
@@ -24157,7 +24132,7 @@ const useFocusGroup = (
24157
24132
 
24158
24133
  installImportMetaCssBuild(import.meta);const rightArrowPath = "M680-480L360-160l-80-80 240-240-240-240 80-80 320 320z";
24159
24134
  const downArrowPath = "M480-280L160-600l80-80 240 240 240-240 80 80-320 320z";
24160
- const css$s = /* css */`
24135
+ const css$t = /* css */`
24161
24136
  .navi_summary_marker {
24162
24137
  width: 1em;
24163
24138
  height: 1em;
@@ -24242,7 +24217,7 @@ const SummaryMarker = ({
24242
24217
  open,
24243
24218
  loading
24244
24219
  }) => {
24245
- import.meta.css = [css$s, "@jsenv/navi/src/field/details/summary_marker.jsx"];
24220
+ import.meta.css = [css$t, "@jsenv/navi/src/field/details/summary_marker.jsx"];
24246
24221
  const showLoading = useDebounceTrue(loading, 300);
24247
24222
  const mountedRef = useRef(false);
24248
24223
  const prevOpenRef = useRef(open);
@@ -24296,7 +24271,7 @@ const SummaryMarker = ({
24296
24271
  });
24297
24272
  };
24298
24273
 
24299
- installImportMetaCssBuild(import.meta);const css$r = /* css */`
24274
+ installImportMetaCssBuild(import.meta);const css$s = /* css */`
24300
24275
  .navi_details {
24301
24276
  position: relative;
24302
24277
  z-index: 1;
@@ -24333,7 +24308,7 @@ installImportMetaCssBuild(import.meta);const css$r = /* css */`
24333
24308
  }
24334
24309
  `;
24335
24310
  const Details = props => {
24336
- import.meta.css = [css$r, "@jsenv/navi/src/field/details/details.jsx"];
24311
+ import.meta.css = [css$s, "@jsenv/navi/src/field/details/details.jsx"];
24337
24312
  const {
24338
24313
  value = "on",
24339
24314
  persists
@@ -24648,7 +24623,7 @@ const fieldPropSet = new Set([
24648
24623
  "data-testid",
24649
24624
  ]);
24650
24625
 
24651
- installImportMetaCssBuild(import.meta);const css$q = /* css */`
24626
+ installImportMetaCssBuild(import.meta);const css$r = /* css */`
24652
24627
  @layer navi {
24653
24628
  label {
24654
24629
  &[data-interactive] {
@@ -24666,7 +24641,7 @@ installImportMetaCssBuild(import.meta);const css$q = /* css */`
24666
24641
  }
24667
24642
  `;
24668
24643
  const Label = props => {
24669
- import.meta.css = [css$q, "@jsenv/navi/src/field/label.jsx"];
24644
+ import.meta.css = [css$r, "@jsenv/navi/src/field/label.jsx"];
24670
24645
  const {
24671
24646
  readOnly,
24672
24647
  disabled,
@@ -24716,7 +24691,7 @@ const reportDisabledToLabel = value => {
24716
24691
  reportDisabled?.(value);
24717
24692
  };
24718
24693
 
24719
- installImportMetaCssBuild(import.meta);const css$p = /* css */`
24694
+ installImportMetaCssBuild(import.meta);const css$q = /* css */`
24720
24695
  @layer navi {
24721
24696
  .navi_checkbox {
24722
24697
  --margin: 3px 3px 3px 4px;
@@ -25108,7 +25083,7 @@ const InputCheckboxDispatcher = props => {
25108
25083
  });
25109
25084
  };
25110
25085
  const InputCheckboxUI = props => {
25111
- import.meta.css = [css$p, "@jsenv/navi/src/field/input_checkbox.jsx"];
25086
+ import.meta.css = [css$q, "@jsenv/navi/src/field/input_checkbox.jsx"];
25112
25087
  const {
25113
25088
  ref,
25114
25089
  /* eslint-disable no-unused-vars */
@@ -25253,11 +25228,10 @@ const InputCheckboxUI = props => {
25253
25228
  children: [jsx("span", {
25254
25229
  className: "navi_checkbox_accent_probe",
25255
25230
  "aria-hidden": "true"
25256
- }), jsx(LoaderBackground, {
25231
+ }), jsx(LoadingOutline, {
25257
25232
  loading: innerLoading,
25258
25233
  inset: -1,
25259
- color: "var(--loader-color)",
25260
- targetSelector: ".navi_checkbox_field"
25234
+ color: "var(--loader-color)"
25261
25235
  }), visualVnode, renderCheckboxMemoized]
25262
25236
  });
25263
25237
  };
@@ -25510,7 +25484,7 @@ forwardRef((props, ref) => {
25510
25484
  });
25511
25485
  });
25512
25486
 
25513
- installImportMetaCssBuild(import.meta);const css$o = /* css */`
25487
+ installImportMetaCssBuild(import.meta);const css$p = /* css */`
25514
25488
  @layer navi {
25515
25489
  .navi_radio {
25516
25490
  --margin: 3px 3px 0 5px;
@@ -25864,7 +25838,7 @@ const InputRadioDispatcher = props => {
25864
25838
  });
25865
25839
  };
25866
25840
  const InputRadioUI = props => {
25867
- import.meta.css = [css$o, "@jsenv/navi/src/field/input_radio.jsx"];
25841
+ import.meta.css = [css$p, "@jsenv/navi/src/field/input_radio.jsx"];
25868
25842
  const {
25869
25843
  ref,
25870
25844
  /* eslint-disable no-unused-vars */
@@ -26029,12 +26003,10 @@ const InputRadioUI = props => {
26029
26003
  children: [jsx("span", {
26030
26004
  className: "navi_radio_accent_probe",
26031
26005
  "aria-hidden": "true"
26032
- }), jsx(LoaderBackground, {
26006
+ }), jsx(LoadingOutline, {
26033
26007
  loading: innerLoading,
26034
26008
  inset: -1,
26035
- targetSelector: ".navi_radio_field",
26036
- color: "var(--loader-color)",
26037
- borderRadius: appearance === "radio" ? "50%" : "inherit"
26009
+ color: "var(--loader-color)"
26038
26010
  }), visualVNode, renderRadioMemoized]
26039
26011
  });
26040
26012
  };
@@ -26096,7 +26068,7 @@ const InputRadioWithAction = () => {
26096
26068
  throw new Error(`<Input type="radio" /> with an action make no sense. Use <RadioList action={something} /> instead`);
26097
26069
  };
26098
26070
 
26099
- installImportMetaCssBuild(import.meta);const css$n = /* css */`
26071
+ installImportMetaCssBuild(import.meta);const css$o = /* css */`
26100
26072
  @layer navi {
26101
26073
  .navi_input_range {
26102
26074
  --border-radius: 6px;
@@ -26358,7 +26330,7 @@ const InputRangeDispatcher = props => {
26358
26330
  });
26359
26331
  };
26360
26332
  const InputRangeUI = props => {
26361
- import.meta.css = [css$n, "@jsenv/navi/src/field/input_range.jsx"];
26333
+ import.meta.css = [css$o, "@jsenv/navi/src/field/input_range.jsx"];
26362
26334
  const {
26363
26335
  ref,
26364
26336
  onInput,
@@ -26495,7 +26467,7 @@ const InputRangeUI = props => {
26495
26467
  children: [jsx("span", {
26496
26468
  className: "navi_input_range_accent_probe",
26497
26469
  "aria-hidden": "true"
26498
- }), jsx(LoaderBackground, {
26470
+ }), jsx(LoadingOutline, {
26499
26471
  loading: innerLoading,
26500
26472
  color: "var(--loader-color)",
26501
26473
  inset: -1
@@ -26635,7 +26607,7 @@ const SearchSvg = () => jsx("svg", {
26635
26607
  })
26636
26608
  });
26637
26609
 
26638
- installImportMetaCssBuild(import.meta);const css$m = /* css */`
26610
+ installImportMetaCssBuild(import.meta);const css$n = /* css */`
26639
26611
  @layer navi {
26640
26612
  .navi_separator {
26641
26613
  --size: 1px;
@@ -26675,7 +26647,7 @@ const Separator = ({
26675
26647
  vertical,
26676
26648
  ...props
26677
26649
  }) => {
26678
- import.meta.css = [css$m, "@jsenv/navi/src/layout/separator.jsx"];
26650
+ import.meta.css = [css$n, "@jsenv/navi/src/layout/separator.jsx"];
26679
26651
  return jsx(Box, {
26680
26652
  as: vertical ? "span" : "hr",
26681
26653
  ...props,
@@ -27087,7 +27059,7 @@ const RenderWindowContext = createContext(null);
27087
27059
  // Carries the separator element/function down to each ListItem so separators
27088
27060
  // are only rendered between items that actually mount (post-filter, post-window).
27089
27061
  const SeparatorContext = createContext(null);
27090
- const css$l = /* css */`
27062
+ const css$m = /* css */`
27091
27063
  @layer navi {
27092
27064
  .navi_list_container {
27093
27065
  --list-outline-width: 1px;
@@ -27514,7 +27486,7 @@ const ListDispatcher = props => {
27514
27486
  });
27515
27487
  };
27516
27488
  const ListUI = props => {
27517
- import.meta.css = [css$l, "@jsenv/navi/src/field/list/list.jsx"];
27489
+ import.meta.css = [css$m, "@jsenv/navi/src/field/list/list.jsx"];
27518
27490
  const {
27519
27491
  ref,
27520
27492
  renderBudget = RENDER_BUDGET_DEFAULT,
@@ -28993,7 +28965,7 @@ installImportMetaCssBuild(import.meta);/**
28993
28965
  * - <InputCheckbox /> for type="checkbox"
28994
28966
  * - <InputRadio /> for type="radio"
28995
28967
  */
28996
- const css$k = /* css */`
28968
+ const css$l = /* css */`
28997
28969
  @layer navi {
28998
28970
  .navi_input {
28999
28971
  --border-radius: 2px;
@@ -29247,7 +29219,7 @@ const InputTextualDispatcher = props => {
29247
29219
  };
29248
29220
  const InputNativeContext = createContext(null);
29249
29221
  const InputTextualUI = props => {
29250
- import.meta.css = [css$k, "@jsenv/navi/src/field/input_textual.jsx"];
29222
+ import.meta.css = [css$l, "@jsenv/navi/src/field/input_textual.jsx"];
29251
29223
  const {
29252
29224
  ref,
29253
29225
  type,
@@ -29392,7 +29364,7 @@ const InputTextualUI = props => {
29392
29364
  autoFocus: undefined // See use_auto_focus.js
29393
29365
  ,
29394
29366
 
29395
- children: [jsx(LoaderBackground, {
29367
+ children: [jsx(LoadingOutline, {
29396
29368
  loading: innerLoading,
29397
29369
  color: "var(--loader-color)",
29398
29370
  inset: -1
@@ -29868,7 +29840,7 @@ installImportMetaCssBuild(import.meta);/**
29868
29840
  * This means an editable thing MUST have a parent with position relative that wraps the content and the eventual editable input
29869
29841
  *
29870
29842
  */
29871
- const css$j = /* css */`
29843
+ const css$k = /* css */`
29872
29844
  .navi_editable_wrapper {
29873
29845
  --inset-top: 0px;
29874
29846
  --inset-right: 0px;
@@ -29917,7 +29889,7 @@ const useEditionController = () => {
29917
29889
  };
29918
29890
  };
29919
29891
  const Editable = props => {
29920
- import.meta.css = [css$j, "@jsenv/navi/src/field/edition/editable.jsx"];
29892
+ import.meta.css = [css$k, "@jsenv/navi/src/field/edition/editable.jsx"];
29921
29893
  let {
29922
29894
  children,
29923
29895
  action,
@@ -30331,7 +30303,7 @@ const FormWithAction = props => {
30331
30303
  // form.dispatchEvent(customEvent);
30332
30304
  // };
30333
30305
 
30334
- installImportMetaCssBuild(import.meta);const css$i = /* css */`
30306
+ installImportMetaCssBuild(import.meta);const css$j = /* css */`
30335
30307
  .navi_group {
30336
30308
  --border-width: 1px;
30337
30309
 
@@ -30428,7 +30400,7 @@ const Group = ({
30428
30400
  vertical = row,
30429
30401
  ...props
30430
30402
  }) => {
30431
- import.meta.css = [css$i, "@jsenv/navi/src/field/group.jsx"];
30403
+ import.meta.css = [css$j, "@jsenv/navi/src/field/group.jsx"];
30432
30404
  if (typeof borderWidth === "string") {
30433
30405
  borderWidth = parseFloat(borderWidth);
30434
30406
  }
@@ -30619,7 +30591,7 @@ const useCleanup = () => {
30619
30591
  return cleanupMethods;
30620
30592
  };
30621
30593
 
30622
- installImportMetaCssBuild(import.meta);const css$h = /* css */`
30594
+ installImportMetaCssBuild(import.meta);const css$i = /* css */`
30623
30595
  .navi_dialog {
30624
30596
  &[open] {
30625
30597
  display: flex;
@@ -30632,7 +30604,7 @@ installImportMetaCssBuild(import.meta);const css$h = /* css */`
30632
30604
  }
30633
30605
  `;
30634
30606
  const Dialog = props => {
30635
- import.meta.css = [css$h, "@jsenv/navi/src/popup/dialog.jsx"];
30607
+ import.meta.css = [css$i, "@jsenv/navi/src/popup/dialog.jsx"];
30636
30608
  const {
30637
30609
  children,
30638
30610
  scrollTrap,
@@ -30743,7 +30715,7 @@ const requestDialogClose = (popoverElement, {
30743
30715
  });
30744
30716
  };
30745
30717
 
30746
- installImportMetaCssBuild(import.meta);const css$g = /* css */`
30718
+ installImportMetaCssBuild(import.meta);const css$h = /* css */`
30747
30719
  .navi_popover_backdrop {
30748
30720
  position: fixed;
30749
30721
  inset: 0;
@@ -30759,7 +30731,7 @@ installImportMetaCssBuild(import.meta);const css$g = /* css */`
30759
30731
  }
30760
30732
  `;
30761
30733
  const Popover = props => {
30762
- import.meta.css = [css$g, "@jsenv/navi/src/popup/popover.jsx"];
30734
+ import.meta.css = [css$h, "@jsenv/navi/src/popup/popover.jsx"];
30763
30735
  const {
30764
30736
  scrollTrap,
30765
30737
  pointerTrap,
@@ -30961,7 +30933,7 @@ const requestPopoverClose = (popoverElement, {
30961
30933
  });
30962
30934
  };
30963
30935
 
30964
- installImportMetaCssBuild(import.meta);const css$f = /* css */`
30936
+ installImportMetaCssBuild(import.meta);const css$g = /* css */`
30965
30937
  @layer navi {
30966
30938
  .navi_select {
30967
30939
  --select-border-radius: 2px;
@@ -31309,7 +31281,7 @@ const SelectDispatcher = props => {
31309
31281
  });
31310
31282
  };
31311
31283
  const SelectUI = props => {
31312
- import.meta.css = [css$f, "@jsenv/navi/src/field/select.jsx"];
31284
+ import.meta.css = [css$g, "@jsenv/navi/src/field/select.jsx"];
31313
31285
  const {
31314
31286
  placeholder = "Select…",
31315
31287
  trigger,
@@ -31359,7 +31331,7 @@ const SelectUI = props => {
31359
31331
  },
31360
31332
  pseudoClasses: SelectPseudoClasses,
31361
31333
  pseudoElements: SelectPseudoElements,
31362
- children: [jsx(LoaderBackground, {
31334
+ children: [jsx(LoadingOutline, {
31363
31335
  loading: innerLoading,
31364
31336
  color: "var(--loader-color)",
31365
31337
  inset: -1
@@ -32501,7 +32473,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
32501
32473
 
32502
32474
  const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
32503
32475
 
32504
- installImportMetaCssBuild(import.meta);const css$e = /* css */`
32476
+ installImportMetaCssBuild(import.meta);const css$f = /* css */`
32505
32477
  .navi_table_drag_clone_container {
32506
32478
  position: absolute;
32507
32479
  top: var(--table-visual-top);
@@ -32681,7 +32653,7 @@ const moveItem = (array, indexA, indexB) => {
32681
32653
  return newArray;
32682
32654
  };
32683
32655
  const TableDragCloneContainer = forwardRef((props, ref) => {
32684
- import.meta.css = [css$e, "@jsenv/navi/src/field/table/drag/table_drag.jsx"];
32656
+ import.meta.css = [css$f, "@jsenv/navi/src/field/table/drag/table_drag.jsx"];
32685
32657
  const {
32686
32658
  tableId
32687
32659
  } = props;
@@ -32979,7 +32951,7 @@ installImportMetaCssBuild(import.meta);const ROW_MIN_HEIGHT = 30;
32979
32951
  const ROW_MAX_HEIGHT = 100;
32980
32952
  const COLUMN_MIN_WIDTH = 50;
32981
32953
  const COLUMN_MAX_WIDTH = 500;
32982
- const css$d = /* css */`
32954
+ const css$e = /* css */`
32983
32955
  @layer navi {
32984
32956
  .navi_table {
32985
32957
  --table-resizer-handle-color: #063b7c;
@@ -33139,7 +33111,7 @@ const css$d = /* css */`
33139
33111
 
33140
33112
  // Column resize components
33141
33113
  const TableColumnResizer = props => {
33142
- import.meta.css = [css$d, "@jsenv/navi/src/field/table/resize/table_resize.jsx"];
33114
+ import.meta.css = [css$e, "@jsenv/navi/src/field/table/resize/table_resize.jsx"];
33143
33115
  const defaultRef = useRef();
33144
33116
  const ref = props.ref || defaultRef;
33145
33117
  return jsxs("div", {
@@ -33606,7 +33578,7 @@ const findPreviousTableRow = currentRow => {
33606
33578
  return currentIndex > 0 ? allRows[currentIndex - 1] : null;
33607
33579
  };
33608
33580
 
33609
- installImportMetaCssBuild(import.meta);const css$c = /* css */`
33581
+ installImportMetaCssBuild(import.meta);const css$d = /* css */`
33610
33582
  @layer navi {
33611
33583
  .navi_table {
33612
33584
  --selection-border-color: var(--navi-selection-border-color, #0078d4);
@@ -33708,7 +33680,7 @@ const useTableSelectionController = ({
33708
33680
  onSelectionChange,
33709
33681
  selectionColor
33710
33682
  }) => {
33711
- import.meta.css = [css$c, "@jsenv/navi/src/field/table/selection/table_selection.jsx"];
33683
+ import.meta.css = [css$d, "@jsenv/navi/src/field/table/selection/table_selection.jsx"];
33712
33684
  const selectionController = useSelectionController({
33713
33685
  elementRef: tableRef,
33714
33686
  layout: "grid",
@@ -34179,7 +34151,7 @@ const useTableStickyContextValue = ({
34179
34151
  };
34180
34152
 
34181
34153
  installImportMetaCssBuild(import.meta);// TODO: sticky left/top frontier should likely use "followPosition"
34182
- const css$b = /* css */`
34154
+ const css$c = /* css */`
34183
34155
  @layer navi {
34184
34156
  .navi_table {
34185
34157
  --sticky-frontier-color: #c0c0c0;
@@ -34422,7 +34394,7 @@ const css$b = /* css */`
34422
34394
  const TableStickyFrontier = ({
34423
34395
  tableRef
34424
34396
  }) => {
34425
- import.meta.css = [css$b, "@jsenv/navi/src/field/table/sticky/table_sticky.jsx"];
34397
+ import.meta.css = [css$c, "@jsenv/navi/src/field/table/sticky/table_sticky.jsx"];
34426
34398
  const stickyLeftFrontierGhostRef = useRef();
34427
34399
  const stickyLeftFrontierPreviewRef = useRef();
34428
34400
  const stickyTopFrontierGhostRef = useRef();
@@ -34651,7 +34623,7 @@ const initMoveStickyFrontierViaPointer = (pointerdownEvent, {
34651
34623
  * inset 0 -1px 0 0 color; // Bottom border
34652
34624
  */
34653
34625
 
34654
- const css$a = /* css */ `
34626
+ const css$b = /* css */ `
34655
34627
  .navi_table_root {
34656
34628
  position: relative;
34657
34629
  max-width: var(--table-max-width, none);
@@ -34854,7 +34826,7 @@ const css$a = /* css */ `
34854
34826
  }
34855
34827
  `;
34856
34828
 
34857
- installImportMetaCssBuild(import.meta);const css$9 = /* css */`
34829
+ installImportMetaCssBuild(import.meta);const css$a = /* css */`
34858
34830
  .navi_table_ui {
34859
34831
  position: fixed;
34860
34832
  inset: 0;
@@ -34865,7 +34837,7 @@ installImportMetaCssBuild(import.meta);const css$9 = /* css */`
34865
34837
  }
34866
34838
  `;
34867
34839
  const TableUI = forwardRef((props, ref) => {
34868
- import.meta.css = [css$9, "@jsenv/navi/src/field/table/table_ui.jsx"];
34840
+ import.meta.css = [css$a, "@jsenv/navi/src/field/table/table_ui.jsx"];
34869
34841
  const {
34870
34842
  tableRef,
34871
34843
  tableId,
@@ -34971,7 +34943,7 @@ const RowIndexContext = createContext();
34971
34943
  const TableSectionContext = createContext();
34972
34944
  const useIsInTableHead = () => useContext(TableSectionContext) === "head";
34973
34945
  const Table = props => {
34974
- import.meta.css = [css$a, "@jsenv/navi/src/field/table/table.jsx"];
34946
+ import.meta.css = [css$b, "@jsenv/navi/src/field/table/table.jsx"];
34975
34947
  const tableDefaultRef = useRef();
34976
34948
  const tableDefaultId = `table-${useId()}`;
34977
34949
  const {
@@ -35868,7 +35840,7 @@ const KeyboardShortcutAriaElement = ({
35868
35840
  });
35869
35841
  };
35870
35842
 
35871
- installImportMetaCssBuild(import.meta);const css$8 = /* css */`
35843
+ installImportMetaCssBuild(import.meta);const css$9 = /* css */`
35872
35844
  @layer navi {
35873
35845
  .navi_clipboard_container {
35874
35846
  --height: 1.5em;
@@ -35900,7 +35872,7 @@ const ButtonCopyToClipboard = ({
35900
35872
  children,
35901
35873
  ...props
35902
35874
  }) => {
35903
- import.meta.css = [css$8, "@jsenv/navi/src/field/button_copy_to_clipboard.jsx"];
35875
+ import.meta.css = [css$9, "@jsenv/navi/src/field/button_copy_to_clipboard.jsx"];
35904
35876
  const [copied, setCopied] = useState(false);
35905
35877
  const renderedRef = useRef();
35906
35878
  useEffect(() => {
@@ -35981,7 +35953,7 @@ const Address = ({
35981
35953
  });
35982
35954
  };
35983
35955
 
35984
- installImportMetaCssBuild(import.meta);const css$7 = /* css */`
35956
+ installImportMetaCssBuild(import.meta);const css$8 = /* css */`
35985
35957
  @layer navi {
35986
35958
  }
35987
35959
  .navi_badge {
@@ -36015,7 +35987,7 @@ const Badge = ({
36015
35987
  className,
36016
35988
  ...props
36017
35989
  }) => {
36018
- import.meta.css = [css$7, "@jsenv/navi/src/text/badge.jsx"];
35990
+ import.meta.css = [css$8, "@jsenv/navi/src/text/badge.jsx"];
36019
35991
  const defaultRef = useRef();
36020
35992
  const ref = props.ref || defaultRef;
36021
35993
  useAccentColorAttributes(ref, null);
@@ -36040,7 +36012,7 @@ const BadgeStyleCSSVars$1 = {
36040
36012
  fontSize: "--font-size"
36041
36013
  };
36042
36014
 
36043
- const LoadingDots = () => {
36015
+ const LoadingDotsSvg = () => {
36044
36016
  return jsxs("svg", {
36045
36017
  viewBox: "0 0 200 200",
36046
36018
  width: "100%",
@@ -36105,7 +36077,7 @@ const formatNumber = (value, { lang } = {}) => {
36105
36077
  return new Intl.NumberFormat(lang).format(value);
36106
36078
  };
36107
36079
 
36108
- installImportMetaCssBuild(import.meta);const css$6 = /* css */`
36080
+ installImportMetaCssBuild(import.meta);const css$7 = /* css */`
36109
36081
  @layer navi {
36110
36082
  }
36111
36083
  .navi_text.navi_badge_count {
@@ -36218,7 +36190,7 @@ const BadgeCount = ({
36218
36190
  lineLayout,
36219
36191
  ...props
36220
36192
  }) => {
36221
- import.meta.css = [css$6, "@jsenv/navi/src/text/badge_count.jsx"];
36193
+ import.meta.css = [css$7, "@jsenv/navi/src/text/badge_count.jsx"];
36222
36194
  const defaultRef = useRef();
36223
36195
  const ref = props.ref || defaultRef;
36224
36196
  useAccentColorAttributes(ref, null);
@@ -36321,7 +36293,7 @@ const BadgeCountEllipse = ({
36321
36293
  styleCSSVars: BadgeStyleCSSVars,
36322
36294
  spacing: "pre",
36323
36295
  children: loading ? jsx(Icon, {
36324
- children: jsx(LoadingDots, {})
36296
+ children: jsx(LoadingDotsSvg, {})
36325
36297
  }) : children
36326
36298
  });
36327
36299
  };
@@ -36349,7 +36321,7 @@ const BadgeCountCircle = ({
36349
36321
  styleCSSVars: BadgeStyleCSSVars,
36350
36322
  spacing: "pre",
36351
36323
  children: loading ? jsx(Icon, {
36352
- children: jsx(LoadingDots, {})
36324
+ children: jsx(LoadingDotsSvg, {})
36353
36325
  }) : jsx("span", {
36354
36326
  className: "navi_badge_count_text",
36355
36327
  children: children
@@ -36357,7 +36329,7 @@ const BadgeCountCircle = ({
36357
36329
  });
36358
36330
  };
36359
36331
 
36360
- installImportMetaCssBuild(import.meta);const css$5 = /* css */`
36332
+ installImportMetaCssBuild(import.meta);const css$6 = /* css */`
36361
36333
  @layer navi {
36362
36334
  .navi_caption {
36363
36335
  --color: #6b7280;
@@ -36378,7 +36350,7 @@ const Caption = ({
36378
36350
  className,
36379
36351
  ...rest
36380
36352
  }) => {
36381
- import.meta.css = [css$5, "@jsenv/navi/src/text/caption.jsx"];
36353
+ import.meta.css = [css$6, "@jsenv/navi/src/text/caption.jsx"];
36382
36354
  return jsx(Text, {
36383
36355
  as: "small",
36384
36356
  size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
@@ -36855,7 +36827,7 @@ const interpolate = (template, values) => {
36855
36827
  });
36856
36828
  };
36857
36829
 
36858
- installImportMetaCssBuild(import.meta);const css$4 = /* css */`
36830
+ installImportMetaCssBuild(import.meta);const css$5 = /* css */`
36859
36831
  @layer navi {
36860
36832
  .navi_quantity {
36861
36833
  --unit-color: color-mix(in srgb, currentColor 50%, white);
@@ -36960,7 +36932,7 @@ const Quantity = ({
36960
36932
  bold = true,
36961
36933
  ...props
36962
36934
  }) => {
36963
- import.meta.css = [css$4, "@jsenv/navi/src/text/quantity.jsx"];
36935
+ import.meta.css = [css$5, "@jsenv/navi/src/text/quantity.jsx"];
36964
36936
  const value = parseQuantityValue(children);
36965
36937
  const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
36966
36938
  const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
@@ -36990,8 +36962,8 @@ const Quantity = ({
36990
36962
  children: [jsx("span", {
36991
36963
  className: "navi_quantity_value",
36992
36964
  children: loading ? jsx(Icon, {
36993
- flowInline: true,
36994
- children: jsx(LoadingDots, {})
36965
+ inline: true,
36966
+ children: jsx(LoadingDotsSvg, {})
36995
36967
  }) : valueFormatted
36996
36968
  }), unit && jsx(Unit, {
36997
36969
  value: value,
@@ -37049,7 +37021,7 @@ const parseQuantityValue = children => {
37049
37021
  return Number.isNaN(parsed) ? children : parsed;
37050
37022
  };
37051
37023
 
37052
- installImportMetaCssBuild(import.meta);const css$3 = /* css */`
37024
+ installImportMetaCssBuild(import.meta);const css$4 = /* css */`
37053
37025
  @layer navi {
37054
37026
  .navi_meter {
37055
37027
  --loader-color: var(--navi-loader-color);
@@ -37129,8 +37101,8 @@ installImportMetaCssBuild(import.meta);const css$3 = /* css */`
37129
37101
  }
37130
37102
 
37131
37103
  &[data-accent-needs-dark-fg] {
37132
- --x-color: white;
37133
- --x-shadow-color: black;
37104
+ --x-color: black;
37105
+ --x-shadow-color: white;
37134
37106
  }
37135
37107
 
37136
37108
  /* When caption is shown, the track takes the full height */
@@ -37187,7 +37159,7 @@ const Meter = ({
37187
37159
  style,
37188
37160
  ...rest
37189
37161
  }) => {
37190
- import.meta.css = [css$3, "@jsenv/navi/src/text/meter.jsx"];
37162
+ import.meta.css = [css$4, "@jsenv/navi/src/text/meter.jsx"];
37191
37163
  const defaultRef = useRef();
37192
37164
  const ref = rest.ref || defaultRef;
37193
37165
  value = Number(value);
@@ -37250,7 +37222,7 @@ const Meter = ({
37250
37222
  ...rest,
37251
37223
  children: jsxs("span", {
37252
37224
  className: "navi_meter_track_container",
37253
- children: [jsx(LoaderBackground, {
37225
+ children: [jsx(LoadingOutline, {
37254
37226
  loading: loading,
37255
37227
  color: "var(--loader-color)",
37256
37228
  inset: -1
@@ -37314,10 +37286,100 @@ const Paragraph = props => {
37314
37286
  });
37315
37287
  };
37316
37288
 
37317
- const Image = props => {
37289
+ installImportMetaCssBuild(import.meta);const css$3 = /* css */`
37290
+ @keyframes navi_image_shimmer {
37291
+ 0% {
37292
+ background-position: -200% 0;
37293
+ }
37294
+ 100% {
37295
+ background-position: 200% 0;
37296
+ }
37297
+ }
37298
+ .navi_image {
37299
+ &[navi-placeholder] {
37300
+ background-image:
37301
+ linear-gradient(
37302
+ 105deg,
37303
+ transparent 30%,
37304
+ color-mix(
37305
+ in srgb,
37306
+ var(--placeholder-color) 0%,
37307
+ var(--placeholder-shimmer-color) 14%
37308
+ )
37309
+ 50%,
37310
+ transparent 70%
37311
+ ),
37312
+ radial-gradient(
37313
+ ellipse at 40% 40%,
37314
+ color-mix(
37315
+ in srgb,
37316
+ var(--placeholder-color) 70%,
37317
+ var(--placeholder-shimmer-color) 30%
37318
+ )
37319
+ 0%,
37320
+ var(--placeholder-color) 70%
37321
+ );
37322
+ background-size:
37323
+ 200% 100%,
37324
+ 100% 100%;
37325
+ animation: navi_image_shimmer 2s linear infinite;
37326
+ }
37327
+ }
37328
+ `;
37329
+ const DEFAULT_PLACEHOLDER_LIGHT = "#d4d8dd";
37330
+ const DEFAULT_PLACEHOLDER_DARK = "#374151";
37331
+
37332
+ /**
37333
+ * @param {string|false} [props.placeholderColor] - Background color shown while the image loads.
37334
+ * Defaults to a light gray. Pass `false` to disable.
37335
+ * @param {boolean} [props.placeholderDark] - Use a dark default placeholder color,
37336
+ * suited for images displayed on a dark background. Also switches the shimmer
37337
+ * highlight to mix with black instead of white.
37338
+ */
37339
+ const Image = ({
37340
+ placeholderColor,
37341
+ placeholderDark = false,
37342
+ ...rest
37343
+ }) => {
37344
+ import.meta.css = [css$3, "@jsenv/navi/src/graphic/image.jsx"];
37345
+ const loadedRef = useRef();
37346
+ let resolvedPlaceholder = placeholderColor;
37347
+ if (resolvedPlaceholder === undefined) {
37348
+ resolvedPlaceholder = placeholderDark ? DEFAULT_PLACEHOLDER_DARK : DEFAULT_PLACEHOLDER_LIGHT;
37349
+ }
37318
37350
  return jsx(Box, {
37351
+ ...rest,
37352
+ as: "img",
37353
+ baseClassName: "navi_image",
37354
+ "navi-placeholder": loadedRef.current ? undefined : "",
37355
+ style: {
37356
+ "--placeholder-color": resolvedPlaceholder || undefined,
37357
+ "--placeholder-shimmer-color": placeholderDark ? "black" : "white",
37358
+ ...rest.style
37359
+ },
37360
+ onLoad: e => {
37361
+ const imageEl = e.currentTarget;
37362
+ imageEl.removeAttribute("navi-placeholder");
37363
+ imageEl.setAttribute("navi-loaded", "");
37364
+ rest.onLoad?.(e);
37365
+ }
37366
+ });
37367
+ };
37368
+
37369
+ const LoadingIndicator = ({
37370
+ variant = "circle",
37371
+ ...props
37372
+ }) => {
37373
+ if (variant === "dots") {
37374
+ return jsx(Icon, {
37375
+ ...props,
37376
+ children: jsx(LoadingDotsSvg, {})
37377
+ });
37378
+ }
37379
+ return jsx(Icon, {
37380
+ circle: true,
37319
37381
  ...props,
37320
- as: "img"
37382
+ children: jsx(LoadingIndicatorFluid, {})
37321
37383
  });
37322
37384
  };
37323
37385
 
@@ -37911,5 +37973,5 @@ const UserSvg = () => jsx("svg", {
37911
37973
  })
37912
37974
  });
37913
37975
 
37914
- export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, Box, Button, ButtonCopyToClipboard, Caption, CheckSvg, Checkbox, CheckboxList, CloseSvg, Code, Col, Colgroup, ConstructionSvg, Details, Dialog, DialogLayout, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemFooter, ListItemGroup, ListItemHeader, Loading, MessageBox, Meter, Nav, NaviDebug, Paragraph, Popover, Quantity, QuantityIntl, Radio, RadioList, Route, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectionContext, Separator, SettingsSvg, SidePanel, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, actionRunEffect, addCustomMessage, anyMatchingRouteSignal, applySearch, arraySignalMembership, compareTwoJsValues, createAction, createAvailableConstraint, createIntl, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, filterTableSelection, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, requestListClose, requestListOpen, rerunActions, resource, route, routeAction, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, syncOwnedResourceToSignals, syncResourceToSignals, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, useRouteStatus, useRunOnMount, useSearchText, useSelectRequestClose, useSelectableElement, useSelectionController, useSidePanelClose, useSignalSync, useStateArray, useTitleLevel, useUrlSearchParam, valueInLocalStorage, windowWidthSignal };
37976
+ export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, Box, Button, ButtonCopyToClipboard, Caption, CheckSvg, Checkbox, CheckboxList, CloseSvg, Code, Col, Colgroup, ConstructionSvg, Details, Dialog, DialogLayout, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemFooter, ListItemGroup, ListItemHeader, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, MessageBox, Meter, Nav, NaviDebug, Paragraph, Popover, Quantity, QuantityIntl, Radio, RadioList, Route, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectionContext, Separator, SettingsSvg, SidePanel, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, actionRunEffect, addCustomMessage, anyMatchingRouteSignal, applySearch, arraySignalMembership, compareTwoJsValues, createAction, createAvailableConstraint, createIntl, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, filterTableSelection, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, requestListClose, requestListOpen, rerunActions, resource, route, routeAction, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, syncOwnedResourceToSignals, syncResourceToSignals, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, useRouteStatus, useRunOnMount, useSearchText, useSelectRequestClose, useSelectableElement, useSelectionController, useSidePanelClose, useSignalSync, useStateArray, useTitleLevel, useUrlSearchParam, valueInLocalStorage, windowWidthSignal };
37915
37977
  //# sourceMappingURL=jsenv_navi.js.map