@provex/components 1.11.0 → 2.0.0

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/index.cjs CHANGED
@@ -68,7 +68,7 @@ var CurrencyIcon = ({
68
68
  }
69
69
  );
70
70
  }
71
- const zoom = useZoom ? currency.zoom ?? 1.5 : 1;
71
+ const zoom = useZoom ? currency.zoom : 1;
72
72
  const objectFit = "cover";
73
73
  return /* @__PURE__ */ jsxRuntime.jsx(
74
74
  "span",
@@ -253,12 +253,13 @@ function Popover({
253
253
  const [position, setPosition] = React.useState(null);
254
254
  const [triggerWidth, setTriggerWidth] = React.useState(void 0);
255
255
  React.useEffect(() => {
256
- if (!isOpen || !triggerRef.current) return;
256
+ const triggerElement = triggerRef.current;
257
+ const popoverElement = popoverRef.current;
258
+ if (!isOpen || !triggerElement || !popoverElement) return;
257
259
  const updatePosition = () => {
258
- if (!triggerRef.current || !popoverRef.current) return;
259
- const rect = triggerRef.current.getBoundingClientRect();
260
+ const rect = triggerElement.getBoundingClientRect();
260
261
  if (fullWidth) setTriggerWidth(rect.width);
261
- const popoverRect = popoverRef.current.getBoundingClientRect();
262
+ const popoverRect = popoverElement.getBoundingClientRect();
262
263
  const popoverWidth = popoverRect.width || width || (fullWidth ? rect.width : minWidth);
263
264
  const popoverHeight = popoverRect.height || 400;
264
265
  let top = 0;
@@ -375,6 +376,11 @@ function PopoverSection({ children }) {
375
376
  function PopoverFooter({ children }) {
376
377
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children });
377
378
  }
379
+ var HORIZONTAL_AXIS = { offset: "scrollLeft", size: "scrollWidth", client: "clientWidth" };
380
+ var VERTICAL_AXIS = { offset: "scrollTop", size: "scrollHeight", client: "clientHeight" };
381
+ function scrollAxisKeys(isHorizontal) {
382
+ return isHorizontal ? HORIZONTAL_AXIS : VERTICAL_AXIS;
383
+ }
378
384
  var injectedDirections = /* @__PURE__ */ new Set();
379
385
  function injectScrollbarStyles(direction) {
380
386
  if (typeof document === "undefined") return;
@@ -434,76 +440,45 @@ var ScrollContainer = React.forwardRef(
434
440
  const isHorizontal = direction === "horizontal" || direction === "both";
435
441
  const isScrollbarLeft = scrollbarPosition === "left";
436
442
  injectScrollbarStyles(direction);
443
+ const axis = scrollAxisKeys(isHorizontal);
437
444
  const handleScroll = React.useCallback((e) => {
438
445
  onScroll?.(e);
439
- if (isUpdatingScroll.current) return;
440
- if (onScrollPositionChange) {
441
- const target = e.currentTarget;
442
- if (isHorizontal) {
443
- const maxScroll = target.scrollWidth - target.clientWidth;
444
- if (maxScroll > 0) {
445
- onScrollPositionChange(target.scrollLeft / maxScroll);
446
- }
447
- } else {
448
- const maxScroll = target.scrollHeight - target.clientHeight;
449
- if (maxScroll > 0) {
450
- onScrollPositionChange(target.scrollTop / maxScroll);
451
- }
452
- }
453
- }
454
- }, [isHorizontal, onScroll, onScrollPositionChange]);
446
+ if (isUpdatingScroll.current || !onScrollPositionChange) return;
447
+ const target = e.currentTarget;
448
+ const maxScroll = target[axis.size] - target[axis.client];
449
+ if (maxScroll > 0) onScrollPositionChange(target[axis.offset] / maxScroll);
450
+ }, [axis, onScroll, onScrollPositionChange]);
455
451
  React.useEffect(() => {
456
- if (scrollPosition === void 0) return;
457
452
  const container = scrollRef.current;
458
- if (!container) return;
459
- if (isHorizontal) {
460
- const maxScroll = container.scrollWidth - container.clientWidth;
461
- if (maxScroll > 0) {
462
- const target = scrollPosition * maxScroll;
463
- if (Math.abs(container.scrollLeft - target) > 1) {
464
- isUpdatingScroll.current = true;
465
- container.scrollLeft = target;
466
- requestAnimationFrame(() => {
467
- isUpdatingScroll.current = false;
468
- });
469
- }
470
- }
471
- } else {
472
- const maxScroll = container.scrollHeight - container.clientHeight;
473
- if (maxScroll > 0) {
474
- const target = scrollPosition * maxScroll;
475
- if (Math.abs(container.scrollTop - target) > 1) {
476
- isUpdatingScroll.current = true;
477
- container.scrollTop = target;
478
- requestAnimationFrame(() => {
479
- isUpdatingScroll.current = false;
480
- });
481
- }
482
- }
483
- }
484
- }, [scrollPosition, isHorizontal, scrollRef]);
453
+ if (scrollPosition === void 0 || !container) return;
454
+ const maxScroll = container[axis.size] - container[axis.client];
455
+ if (maxScroll <= 0) return;
456
+ const target = scrollPosition * maxScroll;
457
+ if (Math.abs(container[axis.offset] - target) <= 1) return;
458
+ isUpdatingScroll.current = true;
459
+ container[axis.offset] = target;
460
+ requestAnimationFrame(() => {
461
+ isUpdatingScroll.current = false;
462
+ });
463
+ }, [scrollPosition, axis, scrollRef]);
485
464
  React.useEffect(() => {
486
- if (!scrollToEnd || hasScrolledToEnd.current) return;
487
465
  const container = scrollRef.current;
488
- if (!container) return;
466
+ if (!scrollToEnd || hasScrolledToEnd.current || !container) return;
489
467
  const timeoutId = setTimeout(() => {
490
- if (isHorizontal) {
491
- container.scrollLeft = container.scrollWidth;
492
- } else {
493
- container.scrollTop = container.scrollHeight;
494
- }
468
+ container[axis.offset] = container[axis.size];
495
469
  hasScrolledToEnd.current = true;
496
470
  }, 100);
497
471
  return () => clearTimeout(timeoutId);
498
- }, [scrollToEnd, isHorizontal, scrollRef, children]);
472
+ }, [scrollToEnd, axis, scrollRef, children]);
499
473
  const defaultOverflowX = isHorizontal ? "auto" : "hidden";
500
474
  const defaultOverflowY = direction === "vertical" || direction === "both" ? "auto" : "hidden";
501
475
  const containerStyle = {
502
- overflowX: style?.overflowX ?? defaultOverflowX,
503
- overflowY: style?.overflowY ?? defaultOverflowY,
504
- ...height !== void 0 ? { height } : {},
505
- ...maxHeight !== void 0 ? { maxHeight } : {},
506
- ...width !== void 0 ? { width } : {},
476
+ overflowX: defaultOverflowX,
477
+ // `style` below overrides these defaults
478
+ overflowY: defaultOverflowY,
479
+ height,
480
+ maxHeight,
481
+ width,
507
482
  ...extendToEdges ? { margin: `-${edgePadding}px`, padding: edgePadding } : {},
508
483
  ...isScrollbarLeft ? { direction: "rtl" } : {},
509
484
  ...style
@@ -540,7 +515,7 @@ function MenuSelect({
540
515
  }) {
541
516
  const [isOpen, setIsOpen] = React.useState(false);
542
517
  const [focusedIndex, setFocusedIndex] = React.useState(-1);
543
- const listRef = React.useRef(null);
518
+ const listboxRef = React.useRef(null);
544
519
  const selectedOption = options.find((o) => o.value === value);
545
520
  const s = SIZES[size];
546
521
  const handleSelect = React.useCallback(
@@ -602,13 +577,8 @@ function MenuSelect({
602
577
  [isOpen, focusedIndex, options, handleSelect, handleToggle, findNextEnabled]
603
578
  );
604
579
  React.useEffect(() => {
605
- if (!isOpen || focusedIndex < 0 || !listRef.current) return;
606
- const listbox = listRef.current.querySelector("[role=listbox]");
607
- if (!listbox) return;
608
- const items = listbox.children;
609
- if (items[focusedIndex]) {
610
- items[focusedIndex].scrollIntoView({ block: "nearest" });
611
- }
580
+ if (!isOpen || focusedIndex < 0) return;
581
+ listboxRef.current?.children[focusedIndex]?.scrollIntoView({ block: "nearest" });
612
582
  }, [isOpen, focusedIndex]);
613
583
  const triggerElement = renderTrigger ? /* @__PURE__ */ jsxRuntime.jsx(
614
584
  "div",
@@ -703,10 +673,9 @@ function MenuSelect({
703
673
  children: /* @__PURE__ */ jsxRuntime.jsx(
704
674
  ScrollContainer,
705
675
  {
706
- ref: listRef,
707
676
  direction: "vertical",
708
677
  maxHeight: maxDropdownHeight,
709
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", onKeyDown: handleKeyDown, children: options.map((option, index) => {
678
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: listboxRef, role: "listbox", onKeyDown: handleKeyDown, children: options.map((option, index) => {
710
679
  const isSelected = option.value === value;
711
680
  const isFocused = index === focusedIndex;
712
681
  const optDisabled = option.isDisabled ?? false;
@@ -769,6 +738,19 @@ function MenuSelect({
769
738
  }
770
739
  );
771
740
  }
741
+ function createItemComparator({
742
+ getVolumeRank,
743
+ statsMap,
744
+ getLabel
745
+ }) {
746
+ return (a, b) => {
747
+ const rankDifference = getVolumeRank ? getVolumeRank(a) - getVolumeRank(b) : 0;
748
+ if (rankDifference !== 0) return rankDifference;
749
+ const countDifference = (statsMap.get(b) ?? 0) - (statsMap.get(a) ?? 0);
750
+ if (countDifference !== 0) return countDifference;
751
+ return getLabel(a).localeCompare(getLabel(b));
752
+ };
753
+ }
772
754
  function MultiSelectFilter({
773
755
  allItems,
774
756
  selectedItems,
@@ -793,23 +775,11 @@ function MultiSelectFilter({
793
775
  () => new Map(itemStats.map((stat) => [stat.item, stat.count])),
794
776
  [itemStats]
795
777
  );
796
- const sortedItems = React.useMemo(() => {
797
- return Array.from(allItems).sort((a, b) => {
798
- if (getVolumeRank) {
799
- const rankA = getVolumeRank(a);
800
- const rankB = getVolumeRank(b);
801
- if (rankA !== rankB) {
802
- return rankA - rankB;
803
- }
804
- }
805
- const countA = statsMap.get(a) ?? 0;
806
- const countB = statsMap.get(b) ?? 0;
807
- if (countA !== countB) {
808
- return countB - countA;
809
- }
810
- return getLabel(a).localeCompare(getLabel(b));
811
- });
812
- }, [allItems, getVolumeRank, statsMap, getLabel]);
778
+ const compareItems = React.useMemo(
779
+ () => createItemComparator({ getVolumeRank, statsMap, getLabel }),
780
+ [getVolumeRank, statsMap, getLabel]
781
+ );
782
+ const sortedItems = React.useMemo(() => Array.from(allItems).sort(compareItems), [allItems, compareItems]);
813
783
  const handleToggle = (item) => {
814
784
  const newSelection = new Set(localSelection);
815
785
  if (newSelection.has(item)) {
@@ -842,22 +812,8 @@ function MultiSelectFilter({
842
812
  if (isShowingAll) {
843
813
  return sortedItems;
844
814
  }
845
- return Array.from(selectedItems).sort((a, b) => {
846
- if (getVolumeRank) {
847
- const rankA = getVolumeRank(a);
848
- const rankB = getVolumeRank(b);
849
- if (rankA !== rankB) {
850
- return rankA - rankB;
851
- }
852
- }
853
- const countA = statsMap.get(a) ?? 0;
854
- const countB = statsMap.get(b) ?? 0;
855
- if (countA !== countB) {
856
- return countB - countA;
857
- }
858
- return getLabel(a).localeCompare(getLabel(b));
859
- });
860
- }, [isShowingAll, sortedItems, selectedItems, getVolumeRank, statsMap, getLabel]);
815
+ return Array.from(selectedItems).sort(compareItems);
816
+ }, [isShowingAll, sortedItems, selectedItems, compareItems]);
861
817
  const iconItems = itemsToDisplay.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
862
818
  "div",
863
819
  {
@@ -1154,9 +1110,7 @@ function Tooltip({ label, children, isDisabled, placement = "top", display = "in
1154
1110
  React.useEffect(() => {
1155
1111
  if (!visible) return;
1156
1112
  const onOutsidePointerDown = (event) => {
1157
- if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
1158
- setVisible(false);
1159
- }
1113
+ if (!wrapperRef.current?.contains(event.target)) setVisible(false);
1160
1114
  };
1161
1115
  const onScroll = () => setVisible(false);
1162
1116
  const onKeyDown = (event) => {
@@ -1214,9 +1168,14 @@ function Tooltip({ label, children, isDisabled, placement = "top", display = "in
1214
1168
  }
1215
1169
  );
1216
1170
  }
1171
+ function backgroundForVersion(version, colors) {
1172
+ if (version === "v4") return colors.bgV4 ?? colors.bgV3;
1173
+ if (version === "v3") return colors.bgV3;
1174
+ return colors.bgV2;
1175
+ }
1217
1176
  function VersionBadge(props) {
1218
1177
  const { version, colors, style } = props;
1219
- const bgColor = version === "v4" ? colors.bgV4 ?? colors.bgV3 : version === "v3" ? colors.bgV3 : colors.bgV2;
1178
+ const bgColor = backgroundForVersion(version, colors);
1220
1179
  return /* @__PURE__ */ jsxRuntime.jsx(
1221
1180
  "span",
1222
1181
  {