@jsenv/navi 0.12.19 → 0.12.21

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.
@@ -1,5 +1,5 @@
1
1
  import { installImportMetaCss } from "./jsenv_navi_side_effects.js";
2
- import { createIterableWeakSet, createPubSub, createValueEffect, createStyleController, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, resolveCSSColor, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, activeElementSignal, canInterceptKeys, createGroupTransitionController, getElementSignature, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, mergeOneStyle, stringifyStyle, mergeTwoStyles, normalizeStyles, resolveCSSSize, findBefore, findAfter, initFocusGroup, elementIsFocusable, pickLightOrDark, resolveColorLuminance, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
2
+ import { createIterableWeakSet, createPubSub, createValueEffect, createStyleController, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, resolveCSSColor, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, activeElementSignal, canInterceptKeys, createGroupTransitionController, getElementSignature, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, stringifyStyle, mergeOneStyle, mergeTwoStyles, normalizeStyles, resolveCSSSize, findBefore, findAfter, hasCSSSizeUnit, initFocusGroup, elementIsFocusable, pickLightOrDark, resolveColorLuminance, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
3
3
  import { prefixFirstAndIndentRemainingLines } from "@jsenv/humanize";
4
4
  import { effect, signal, computed, batch, useSignal } from "@preact/signals";
5
5
  import { useEffect, useRef, useCallback, useContext, useState, useLayoutEffect, useMemo, useErrorBoundary, useImperativeHandle, useId } from "preact/hooks";
@@ -10249,6 +10249,10 @@ const LAYOUT_PROPS = {
10249
10249
  box: () => {},
10250
10250
  row: () => {},
10251
10251
  column: () => {},
10252
+
10253
+ absolute: applyToCssPropWhenTruthy("position", "absolute", "static"),
10254
+ relative: applyToCssPropWhenTruthy("position", "relative", "static"),
10255
+ fixed: applyToCssPropWhenTruthy("position", "fixed", "static"),
10252
10256
  };
10253
10257
  const OUTER_SPACING_PROPS = {
10254
10258
  margin: PASS_THROUGH,
@@ -10397,6 +10401,8 @@ const POSITION_PROPS = {
10397
10401
  },
10398
10402
  left: PASS_THROUGH,
10399
10403
  top: PASS_THROUGH,
10404
+ bottom: PASS_THROUGH,
10405
+ right: PASS_THROUGH,
10400
10406
 
10401
10407
  translateX: (value) => {
10402
10408
  return { transform: `translateX(${value})` };
@@ -10438,7 +10444,7 @@ const POSITION_PROPS = {
10438
10444
  },
10439
10445
  };
10440
10446
  const TYPO_PROPS = {
10441
- font: PASS_THROUGH,
10447
+ font: applyOnCSSProp("fontFamily"),
10442
10448
  fontFamily: PASS_THROUGH,
10443
10449
  size: applyOnCSSProp("fontSize"),
10444
10450
  fontSize: PASS_THROUGH,
@@ -10517,9 +10523,9 @@ const CONTENT_PROPS = {
10517
10523
  spacing: (value, { layout }) => {
10518
10524
  if (
10519
10525
  layout === "row" ||
10520
- layout === "column"
10521
- // layout === "inline-row" ||
10522
- // layout === "inline-column"
10526
+ layout === "column" ||
10527
+ layout === "inline-row" ||
10528
+ layout === "inline-column"
10523
10529
  ) {
10524
10530
  return {
10525
10531
  gap: resolveSpacingSize(value, "gap"),
@@ -10640,19 +10646,29 @@ const sizeSpacingScale = {
10640
10646
  xl: "2em", // 2 = 32px at 16px base
10641
10647
  xxl: "3em", // 3 = 48px at 16px base
10642
10648
  };
10649
+ sizeSpacingScale.s = sizeSpacingScale.sm;
10650
+ sizeSpacingScale.m = sizeSpacingScale.md;
10651
+ sizeSpacingScale.l = sizeSpacingScale.lg;
10652
+ const sizeSpacingScaleKeys = new Set(Object.keys(sizeSpacingScale));
10653
+ const isSizeSpacingScaleKey = (key) => {
10654
+ return sizeSpacingScaleKeys.has(key);
10655
+ };
10643
10656
  const resolveSpacingSize = (size, property = "padding") => {
10644
10657
  return stringifyStyle(sizeSpacingScale[size] || size, property);
10645
10658
  };
10646
10659
 
10647
10660
  const sizeTypoScale = {
10648
- xxs: "0.625em", // 0.625 = 10px at 16px base (smaller than before for more range)
10649
- xs: "0.75em", // 0.75 = 12px at 16px base
10650
- sm: "0.875em", // 0.875 = 14px at 16px base
10651
- md: "1em", // 1 = 16px at 16px base (base font size)
10652
- lg: "1.125em", // 1.125 = 18px at 16px base
10653
- xl: "1.25em", // 1.25 = 20px at 16px base
10654
- xxl: "1.5em", // 1.5 = 24px at 16px base
10655
- };
10661
+ xxs: "0.625rem", // 0.625 = 10px at 16px base (smaller than before for more range)
10662
+ xs: "0.75rem", // 0.75 = 12px at 16px base
10663
+ sm: "0.875rem", // 0.875 = 14px at 16px base
10664
+ md: "1rem", // 1 = 16px at 16px base (base font size)
10665
+ lg: "1.125rem", // 1.125 = 18px at 16px base
10666
+ xl: "1.25rem", // 1.25 = 20px at 16px base
10667
+ xxl: "1.5rem", // 1.5 = 24px at 16px base
10668
+ };
10669
+ sizeTypoScale.s = sizeTypoScale.sm;
10670
+ sizeTypoScale.m = sizeTypoScale.md;
10671
+ sizeTypoScale.l = sizeTypoScale.lg;
10656
10672
 
10657
10673
  const DEFAULT_DISPLAY_BY_TAG_NAME = {
10658
10674
  "inline": new Set([
@@ -11260,9 +11276,6 @@ const Box = props => {
11260
11276
  row,
11261
11277
  column
11262
11278
  } = rest;
11263
- if (box === "auto") {
11264
- box = Boolean(rest.alignX || rest.alignY);
11265
- }
11266
11279
  if (box) {
11267
11280
  if (inline === undefined) {
11268
11281
  inline = true;
@@ -13641,13 +13654,25 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
13641
13654
  text-overflow: ellipsis;
13642
13655
  overflow: hidden;
13643
13656
  }
13657
+
13658
+ .navi_custom_space {
13659
+ }
13644
13660
  `;
13645
- const INSERTED_SPACE = jsx("span", {
13661
+ const REGULAR_SPACE = jsx("span", {
13646
13662
  "data-navi-space": "",
13647
13663
  children: " "
13648
13664
  });
13665
+ const CustomWidthSpace = ({
13666
+ value
13667
+ }) => {
13668
+ return jsx("span", {
13669
+ className: "navi_custom_space",
13670
+ style: `padding-left: ${value}`,
13671
+ children: "\u200B"
13672
+ });
13673
+ };
13649
13674
  const applySpacingOnTextChildren = (children, spacing) => {
13650
- if (spacing === "pre") {
13675
+ if (spacing === "pre" || spacing === "0" || spacing === 0) {
13651
13676
  return children;
13652
13677
  }
13653
13678
  if (!children) {
@@ -13658,23 +13683,28 @@ const applySpacingOnTextChildren = (children, spacing) => {
13658
13683
  if (childCount <= 1) {
13659
13684
  return children;
13660
13685
  }
13661
-
13662
- // Helper function to check if a value ends with whitespace
13663
- const endsWithWhitespace = value => {
13664
- if (typeof value === "string") {
13665
- return /\s$/.test(value);
13666
- }
13667
- return false;
13668
- };
13669
-
13670
- // Helper function to check if a value starts with whitespace
13671
- const startsWithWhitespace = value => {
13672
- if (typeof value === "string") {
13673
- return /^\s/.test(value);
13686
+ let separator;
13687
+ if (spacing === undefined) {
13688
+ spacing = REGULAR_SPACE;
13689
+ } else if (typeof spacing === "string") {
13690
+ if (isSizeSpacingScaleKey(spacing)) {
13691
+ separator = jsx(CustomWidthSpace, {
13692
+ value: resolveSpacingSize(spacing)
13693
+ });
13694
+ } else if (hasCSSSizeUnit(spacing)) {
13695
+ separator = jsx(CustomWidthSpace, {
13696
+ value: resolveSpacingSize(spacing)
13697
+ });
13698
+ } else {
13699
+ separator = spacing;
13674
13700
  }
13675
- return false;
13676
- };
13677
- const separator = spacing === undefined || spacing === " " ? INSERTED_SPACE : spacing;
13701
+ } else if (typeof spacing === "number") {
13702
+ separator = jsx(CustomWidthSpace, {
13703
+ value: spacing
13704
+ });
13705
+ } else {
13706
+ separator = spacing;
13707
+ }
13678
13708
  const childrenWithGap = [];
13679
13709
  let i = 0;
13680
13710
  while (true) {
@@ -13684,17 +13714,30 @@ const applySpacingOnTextChildren = (children, spacing) => {
13684
13714
  if (i === childCount) {
13685
13715
  break;
13686
13716
  }
13687
-
13688
- // Check if we should skip adding spacing
13689
13717
  const currentChild = childArray[i - 1];
13690
13718
  const nextChild = childArray[i];
13691
- const shouldSkipSpacing = endsWithWhitespace(currentChild) || startsWithWhitespace(nextChild);
13692
- if (!shouldSkipSpacing) {
13693
- childrenWithGap.push(separator);
13719
+ if (endsWithWhitespace(currentChild)) {
13720
+ continue;
13721
+ }
13722
+ if (startsWithWhitespace(nextChild)) {
13723
+ continue;
13694
13724
  }
13725
+ childrenWithGap.push(separator);
13695
13726
  }
13696
13727
  return childrenWithGap;
13697
13728
  };
13729
+ const endsWithWhitespace = jsxChild => {
13730
+ if (typeof jsxChild === "string") {
13731
+ return /\s$/.test(jsxChild);
13732
+ }
13733
+ return false;
13734
+ };
13735
+ const startsWithWhitespace = jsxChild => {
13736
+ if (typeof jsxChild === "string") {
13737
+ return /^\s/.test(jsxChild);
13738
+ }
13739
+ return false;
13740
+ };
13698
13741
  const OverflowPinnedElementContext = createContext(null);
13699
13742
  const Text = props => {
13700
13743
  const {
@@ -13788,6 +13831,10 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
13788
13831
  box-sizing: border-box;
13789
13832
  }
13790
13833
 
13834
+ .navi_icon[data-interactive] {
13835
+ cursor: pointer;
13836
+ }
13837
+
13791
13838
  .navi_icon_char_slot {
13792
13839
  opacity: 0;
13793
13840
  cursor: default;
@@ -13804,6 +13851,7 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
13804
13851
  .navi_icon_foreground > .navi_text {
13805
13852
  display: flex;
13806
13853
  aspect-ratio: 1 / 1;
13854
+ min-width: 0;
13807
13855
  height: 100%;
13808
13856
  max-height: 1em;
13809
13857
  align-items: center;
@@ -13847,6 +13895,7 @@ const Icon = ({
13847
13895
  "aria-label": ariaLabel,
13848
13896
  role,
13849
13897
  decorative = false,
13898
+ onClick,
13850
13899
  ...props
13851
13900
  }) => {
13852
13901
  const innerChildren = href ? jsx("svg", {
@@ -13870,6 +13919,8 @@ const Icon = ({
13870
13919
  baseClassName: "navi_icon",
13871
13920
  "data-width": width,
13872
13921
  "data-height": height,
13922
+ "data-interactive": onClick ? "" : undefined,
13923
+ onClick: onClick,
13873
13924
  children: innerChildren
13874
13925
  });
13875
13926
  }
@@ -13889,16 +13940,16 @@ const Icon = ({
13889
13940
  "data-icon-char": "",
13890
13941
  "data-width": width,
13891
13942
  "data-height": height,
13943
+ "data-interactive": onClick ? "" : undefined,
13944
+ onClick: onClick,
13892
13945
  children: [jsx("span", {
13893
13946
  className: "navi_icon_char_slot",
13894
13947
  "aria-hidden": "true",
13895
13948
  children: invisibleText
13896
- }), jsx("span", {
13949
+ }), jsx(Text, {
13897
13950
  className: "navi_icon_foreground",
13898
- children: jsx(Text, {
13899
- spacing: "pre",
13900
- children: innerChildren
13901
- })
13951
+ spacing: "pre",
13952
+ children: innerChildren
13902
13953
  })]
13903
13954
  });
13904
13955
  };
@@ -13908,6 +13959,7 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
13908
13959
  .navi_link {
13909
13960
  --link-border-radius: 2px;
13910
13961
  --link-outline-color: var(--navi-focus-outline-color);
13962
+ --link-loader-color: var(--navi-loader-color);
13911
13963
  --link-color: rgb(0, 0, 238);
13912
13964
  --link-color-visited: light-dark(#6a1b9a, #ab47bc);
13913
13965
  --link-color-active: red;
@@ -13929,6 +13981,7 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
13929
13981
  position: relative;
13930
13982
  color: var(--x-link-color);
13931
13983
  text-decoration: var(--x-link-text-decoration);
13984
+ vertical-align: middle;
13932
13985
  border-radius: var(--link-border-radius);
13933
13986
  outline-color: var(--link-outline-color);
13934
13987
  cursor: var(--x-link-cursor);
@@ -14089,7 +14142,6 @@ const LinkPlain = props => {
14089
14142
  innerIcon = icon;
14090
14143
  }
14091
14144
  return jsxs(Box, {
14092
- box: "auto",
14093
14145
  ...rest,
14094
14146
  ref: ref,
14095
14147
  as: "a",
@@ -14137,7 +14189,7 @@ const LinkPlain = props => {
14137
14189
  },
14138
14190
  children: [jsx(LoaderBackground, {
14139
14191
  loading: loading,
14140
- color: "light-dark(#355fcc, #3b82f6)"
14192
+ color: "var(--link-loader-color)"
14141
14193
  }), applySpacingOnTextChildren(children, spacing), innerIcon && jsx(Icon, {
14142
14194
  marginLeft: "xxs",
14143
14195
  children: innerIcon
@@ -16771,9 +16823,9 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
16771
16823
  --x-button-color: var(--button-color);
16772
16824
 
16773
16825
  position: relative;
16774
- /* display: inline-flex; */
16775
16826
  box-sizing: border-box;
16776
16827
  padding: 0;
16828
+ vertical-align: middle;
16777
16829
  background: none;
16778
16830
  border: none;
16779
16831
  border-radius: var(--x-button-border-radius);
@@ -16983,7 +17035,6 @@ const ButtonBasic = props => {
16983
17035
  };
16984
17036
  const renderButtonContentMemoized = useCallback(renderButtonContent, []);
16985
17037
  return jsxs(Box, {
16986
- box: "auto",
16987
17038
  ...rest,
16988
17039
  as: "button",
16989
17040
  ref: ref,
@@ -17007,7 +17058,7 @@ const ButtonBasic = props => {
17007
17058
  children: [jsx(LoaderBackground, {
17008
17059
  loading: innerLoading,
17009
17060
  inset: -1,
17010
- color: "var(--loader-color)"
17061
+ color: "var(--button-loader-color)"
17011
17062
  }), renderButtonContentMemoized]
17012
17063
  });
17013
17064
  };
@@ -21540,17 +21591,24 @@ const SVGMaskOverlay = ({
21540
21591
  });
21541
21592
  };
21542
21593
 
21543
- const CSS_VAR_NAME = "--color-contrasting";
21594
+ const CSS_VAR_NAME = "--x-color-contrasting";
21544
21595
 
21545
- const useContrastingColor = (ref) => {
21596
+ const useContrastingColor = (ref, backgroundElementSelector) => {
21546
21597
  useLayoutEffect(() => {
21547
21598
  const el = ref.current;
21548
21599
  if (!el) {
21549
21600
  return;
21550
21601
  }
21602
+ let elementToCheck = el;
21603
+ {
21604
+ elementToCheck = el.querySelector(backgroundElementSelector);
21605
+ if (!elementToCheck) {
21606
+ return;
21607
+ }
21608
+ }
21551
21609
  const lightColor = "var(--navi-color-light)";
21552
21610
  const darkColor = "var(--navi-color-dark)";
21553
- const backgroundColor = getComputedStyle(el).backgroundColor;
21611
+ const backgroundColor = getComputedStyle(elementToCheck).backgroundColor;
21554
21612
  if (!backgroundColor) {
21555
21613
  el.style.removeProperty(CSS_VAR_NAME);
21556
21614
  return;
@@ -21567,45 +21625,65 @@ const useContrastingColor = (ref) => {
21567
21625
 
21568
21626
  installImportMetaCss(import.meta);import.meta.css = /* css */`
21569
21627
  @layer navi {
21570
- .navi_badge_count {
21571
- --border-radius: 1em;
21572
- }
21573
21628
  }
21574
21629
  .navi_badge_count {
21575
- --spacing: 0.3em;
21576
- --size: 1em;
21577
- --x-outer-size: calc(var(--size) + var(--spacing));
21578
- --x-offset-top: calc(0.5 * (var(--x-outer-size) - 1em));
21579
-
21630
+ --x-size: 1.5em;
21631
+ --x-border-radius: var(--border-radius);
21632
+ --x-number-font-size: var(--font-size);
21633
+ position: relative;
21580
21634
  display: inline-block;
21581
- box-sizing: border-box;
21582
- min-width: var(--x-outer-size);
21583
- height: var(--x-outer-size);
21584
- max-height: var(--x-outer-size);
21585
- margin-top: calc(-1 * var(--x-offset-top));
21586
- padding-right: var(--spacing);
21587
- padding-left: var(--spacing);
21588
- color: var(--color, var(--color-contrasting));
21589
- text-align: center;
21590
- line-height: var(--x-outer-size);
21591
- /* vertical-align: middle; */
21635
+
21636
+ color: var(--color, var(--x-color-contrasting));
21637
+ font-size: var(--font-size);
21638
+ vertical-align: middle;
21639
+ border-radius: var(--x-border-radius);
21640
+ }
21641
+ .navi_count_badge_overflow {
21642
+ position: relative;
21643
+ top: -0.1em;
21644
+ }
21645
+ /* Ellipse */
21646
+ .navi_badge_count[data-ellipse] {
21647
+ padding-right: 0.4em;
21648
+ padding-left: 0.4em;
21649
+ background: var(--background);
21650
+ background-color: var(--background-color, var(--background));
21651
+ border-radius: 1em;
21652
+ }
21653
+ /* Circle */
21654
+ .navi_badge_count[data-circle] {
21655
+ width: var(--x-size);
21656
+ height: var(--x-size);
21657
+ }
21658
+ .navi_badge_count_frame {
21659
+ position: absolute;
21660
+ top: 50%;
21661
+ left: 0;
21662
+ width: 100%;
21663
+ height: 100%;
21592
21664
  background: var(--background);
21593
21665
  background-color: var(--background-color, var(--background));
21594
- border-radius: var(--border-radius, 1em);
21666
+ border-radius: inherit;
21667
+ transform: translateY(-50%);
21668
+ }
21669
+ .navi_badge_count_text {
21670
+ position: absolute;
21671
+ top: 50%;
21672
+ left: 50%;
21673
+ font-size: var(--x-number-font-size, inherit);
21674
+ transform: translate(-50%, -50%);
21595
21675
  }
21596
- .navi_badge_count[data-single-digit] {
21597
- --spacing: 0em;
21598
- --size: 1.3em;
21676
+ .navi_badge_count[data-single-char] {
21677
+ --x-border-radius: 100%;
21678
+ --x-number-font-size: unset;
21599
21679
  }
21600
- .navi_badge_count[data-two-digits] {
21601
- --spacing: 0em;
21602
- --size: 1.6em;
21680
+ .navi_badge_count[data-two-chars] {
21681
+ --x-border-radius: 100%;
21682
+ --x-number-font-size: 0.8em;
21603
21683
  }
21604
-
21605
- .navi_count_badge_overflow {
21606
- position: relative;
21607
- top: -0.4em;
21608
- font-size: 0.8em;
21684
+ .navi_badge_count[data-three-chars] {
21685
+ --x-border-radius: 100%;
21686
+ --x-number-font-size: 0.6em;
21609
21687
  }
21610
21688
  `;
21611
21689
  const BadgeStyleCSSVars = {
@@ -21616,50 +21694,121 @@ const BadgeStyleCSSVars = {
21616
21694
  backgroundColor: "--background-color",
21617
21695
  background: "--background",
21618
21696
  borderColor: "--border-color",
21619
- color: "--color"
21697
+ color: "--color",
21698
+ fontSize: "--font-size"
21620
21699
  };
21621
21700
  const BadgeCountOverflow = () => jsx("span", {
21622
21701
  className: "navi_count_badge_overflow",
21623
21702
  children: "+"
21624
21703
  });
21704
+ const MAX_CHAR_AS_CIRCLE = 3;
21625
21705
  const BadgeCount = ({
21626
21706
  children,
21627
- max,
21707
+ max = 99,
21628
21708
  maxElement = jsx(BadgeCountOverflow, {}),
21709
+ // When you use max="none" (or max > 99) it might be a good idea to force ellipse
21710
+ // so that visually the interface do not suddently switch from circle to ellipse depending on the count
21711
+ ellipse,
21629
21712
  ...props
21630
21713
  }) => {
21631
21714
  const defaultRef = useRef();
21632
21715
  const ref = props.ref || defaultRef;
21633
- const numericValue = typeof children === "string" ? parseInt(children, 10) : children;
21634
- // Calculer la valeur à afficher en fonction du paramètre max
21635
- const getDisplayValue = () => {
21636
- if (max === undefined) {
21637
- return children;
21638
- }
21639
- const numericMax = typeof max === "string" ? parseInt(max, 10) : max;
21640
- if (isNaN(numericValue) || isNaN(numericMax)) {
21641
- return children;
21642
- }
21643
- if (numericValue > numericMax) {
21644
- return jsxs(Fragment, {
21645
- children: [children, maxElement]
21646
- });
21647
- }
21648
- return children;
21649
- };
21650
- const displayValue = getDisplayValue();
21651
- useContrastingColor(ref);
21652
- const digitCount = String(numericValue).length;
21653
- return jsx(Text, {
21716
+ useContrastingColor(ref, ".navi_badge_count_visual");
21717
+ const valueRequested = typeof children === "string" ? parseInt(children, 10) : children;
21718
+ const valueDisplayed = applyMaxToValue(max, valueRequested);
21719
+ const hasOverflow = valueDisplayed !== valueRequested;
21720
+ const valueCharCount = String(valueDisplayed).length;
21721
+ const charCount = valueCharCount + (hasOverflow ? 1 : 0);
21722
+ if (charCount > MAX_CHAR_AS_CIRCLE) {
21723
+ ellipse = true;
21724
+ }
21725
+ if (ellipse) {
21726
+ return jsxs(BadgeCountEllipse, {
21727
+ ...props,
21728
+ ref: ref,
21729
+ hasOverflow: hasOverflow,
21730
+ children: [valueDisplayed, hasOverflow && maxElement]
21731
+ });
21732
+ }
21733
+ return jsxs(BadgeCountCircle, {
21734
+ ...props,
21735
+ ref: ref,
21736
+ hasOverflow: hasOverflow,
21737
+ charCount: charCount,
21738
+ children: [valueDisplayed, hasOverflow && maxElement]
21739
+ });
21740
+ };
21741
+ const applyMaxToValue = (max, value) => {
21742
+ if (isNaN(value)) {
21743
+ return value;
21744
+ }
21745
+ if (max === undefined || max === Infinity || max === false || max === "false" || max === "Infinity" || max === "none") {
21746
+ return value;
21747
+ }
21748
+ const numericMax = typeof max === "string" ? parseInt(max, 10) : max;
21749
+ if (isNaN(numericMax)) {
21750
+ return value;
21751
+ }
21752
+ if (value > numericMax) {
21753
+ return numericMax;
21754
+ }
21755
+ return value;
21756
+ };
21757
+ const BadgeCountCircle = ({
21758
+ ref,
21759
+ charCount,
21760
+ hasOverflow,
21761
+ children,
21762
+ ...props
21763
+ }) => {
21764
+ return jsxs(Text, {
21654
21765
  ref: ref,
21655
21766
  className: "navi_badge_count",
21767
+ "data-circle": "",
21656
21768
  bold: true,
21657
- "data-single-digit": digitCount === 1 ? "" : undefined,
21658
- "data-two-digits": digitCount === 2 ? "" : undefined,
21769
+ "data-single-char": charCount === 1 ? "" : undefined,
21770
+ "data-two-chars": charCount === 2 ? "" : undefined,
21771
+ "data-three-chars": charCount === 3 ? "" : undefined,
21772
+ "data-value-overflow": hasOverflow ? "" : undefined,
21659
21773
  ...props,
21660
21774
  styleCSSVars: BadgeStyleCSSVars,
21661
21775
  spacing: "pre",
21662
- children: displayValue
21776
+ children: [jsx("span", {
21777
+ style: "user-select: none",
21778
+ children: "\u200B"
21779
+ }), jsx("span", {
21780
+ className: "navi_badge_count_frame"
21781
+ }), jsx("span", {
21782
+ className: "navi_badge_count_text",
21783
+ children: children
21784
+ }), jsx("span", {
21785
+ style: "user-select: none",
21786
+ children: "\u200B"
21787
+ })]
21788
+ });
21789
+ };
21790
+ const BadgeCountEllipse = ({
21791
+ ref,
21792
+ children,
21793
+ hasOverflow,
21794
+ ...props
21795
+ }) => {
21796
+ return jsxs(Text, {
21797
+ ref: ref,
21798
+ className: "navi_badge_count",
21799
+ bold: true,
21800
+ "data-ellipse": "",
21801
+ "data-value-overflow": hasOverflow ? "" : undefined,
21802
+ ...props,
21803
+ styleCSSVars: BadgeStyleCSSVars,
21804
+ spacing: "pre",
21805
+ children: [jsx("span", {
21806
+ style: "user-select: none",
21807
+ children: "\u200B"
21808
+ }), children, jsx("span", {
21809
+ style: "user-select: none",
21810
+ children: "\u200B"
21811
+ })]
21663
21812
  });
21664
21813
  };
21665
21814