@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.
- package/dist/jsenv_navi.js +258 -109
- package/dist/jsenv_navi.js.map +38 -32
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -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,
|
|
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:
|
|
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
|
-
|
|
10522
|
-
|
|
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.
|
|
10649
|
-
xs: "0.
|
|
10650
|
-
sm: "0.
|
|
10651
|
-
md: "
|
|
10652
|
-
lg: "1.
|
|
10653
|
-
xl: "1.
|
|
10654
|
-
xxl: "1.
|
|
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
|
|
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
|
-
|
|
13663
|
-
|
|
13664
|
-
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
|
|
13670
|
-
|
|
13671
|
-
|
|
13672
|
-
|
|
13673
|
-
|
|
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
|
-
|
|
13676
|
-
|
|
13677
|
-
|
|
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
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
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(
|
|
13949
|
+
}), jsx(Text, {
|
|
13897
13950
|
className: "navi_icon_foreground",
|
|
13898
|
-
|
|
13899
|
-
|
|
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: "
|
|
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(
|
|
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
|
-
--
|
|
21576
|
-
--
|
|
21577
|
-
--x-
|
|
21578
|
-
|
|
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
|
-
|
|
21582
|
-
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
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:
|
|
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-
|
|
21597
|
-
--
|
|
21598
|
-
--size:
|
|
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-
|
|
21601
|
-
--
|
|
21602
|
-
--size:
|
|
21680
|
+
.navi_badge_count[data-two-chars] {
|
|
21681
|
+
--x-border-radius: 100%;
|
|
21682
|
+
--x-number-font-size: 0.8em;
|
|
21603
21683
|
}
|
|
21604
|
-
|
|
21605
|
-
|
|
21606
|
-
|
|
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
|
-
|
|
21634
|
-
|
|
21635
|
-
const
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
}
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
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-
|
|
21658
|
-
"data-two-
|
|
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:
|
|
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
|
|