@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.js CHANGED
@@ -62,7 +62,7 @@ var CurrencyIcon = ({
62
62
  }
63
63
  );
64
64
  }
65
- const zoom = useZoom ? currency.zoom ?? 1.5 : 1;
65
+ const zoom = useZoom ? currency.zoom : 1;
66
66
  const objectFit = "cover";
67
67
  return /* @__PURE__ */ jsx(
68
68
  "span",
@@ -247,12 +247,13 @@ function Popover({
247
247
  const [position, setPosition] = useState(null);
248
248
  const [triggerWidth, setTriggerWidth] = useState(void 0);
249
249
  useEffect(() => {
250
- if (!isOpen || !triggerRef.current) return;
250
+ const triggerElement = triggerRef.current;
251
+ const popoverElement = popoverRef.current;
252
+ if (!isOpen || !triggerElement || !popoverElement) return;
251
253
  const updatePosition = () => {
252
- if (!triggerRef.current || !popoverRef.current) return;
253
- const rect = triggerRef.current.getBoundingClientRect();
254
+ const rect = triggerElement.getBoundingClientRect();
254
255
  if (fullWidth) setTriggerWidth(rect.width);
255
- const popoverRect = popoverRef.current.getBoundingClientRect();
256
+ const popoverRect = popoverElement.getBoundingClientRect();
256
257
  const popoverWidth = popoverRect.width || width || (fullWidth ? rect.width : minWidth);
257
258
  const popoverHeight = popoverRect.height || 400;
258
259
  let top = 0;
@@ -369,6 +370,11 @@ function PopoverSection({ children }) {
369
370
  function PopoverFooter({ children }) {
370
371
  return /* @__PURE__ */ jsx("div", { children });
371
372
  }
373
+ var HORIZONTAL_AXIS = { offset: "scrollLeft", size: "scrollWidth", client: "clientWidth" };
374
+ var VERTICAL_AXIS = { offset: "scrollTop", size: "scrollHeight", client: "clientHeight" };
375
+ function scrollAxisKeys(isHorizontal) {
376
+ return isHorizontal ? HORIZONTAL_AXIS : VERTICAL_AXIS;
377
+ }
372
378
  var injectedDirections = /* @__PURE__ */ new Set();
373
379
  function injectScrollbarStyles(direction) {
374
380
  if (typeof document === "undefined") return;
@@ -428,76 +434,45 @@ var ScrollContainer = forwardRef(
428
434
  const isHorizontal = direction === "horizontal" || direction === "both";
429
435
  const isScrollbarLeft = scrollbarPosition === "left";
430
436
  injectScrollbarStyles(direction);
437
+ const axis = scrollAxisKeys(isHorizontal);
431
438
  const handleScroll = useCallback((e) => {
432
439
  onScroll?.(e);
433
- if (isUpdatingScroll.current) return;
434
- if (onScrollPositionChange) {
435
- const target = e.currentTarget;
436
- if (isHorizontal) {
437
- const maxScroll = target.scrollWidth - target.clientWidth;
438
- if (maxScroll > 0) {
439
- onScrollPositionChange(target.scrollLeft / maxScroll);
440
- }
441
- } else {
442
- const maxScroll = target.scrollHeight - target.clientHeight;
443
- if (maxScroll > 0) {
444
- onScrollPositionChange(target.scrollTop / maxScroll);
445
- }
446
- }
447
- }
448
- }, [isHorizontal, onScroll, onScrollPositionChange]);
440
+ if (isUpdatingScroll.current || !onScrollPositionChange) return;
441
+ const target = e.currentTarget;
442
+ const maxScroll = target[axis.size] - target[axis.client];
443
+ if (maxScroll > 0) onScrollPositionChange(target[axis.offset] / maxScroll);
444
+ }, [axis, onScroll, onScrollPositionChange]);
449
445
  useEffect(() => {
450
- if (scrollPosition === void 0) return;
451
446
  const container = scrollRef.current;
452
- if (!container) return;
453
- if (isHorizontal) {
454
- const maxScroll = container.scrollWidth - container.clientWidth;
455
- if (maxScroll > 0) {
456
- const target = scrollPosition * maxScroll;
457
- if (Math.abs(container.scrollLeft - target) > 1) {
458
- isUpdatingScroll.current = true;
459
- container.scrollLeft = target;
460
- requestAnimationFrame(() => {
461
- isUpdatingScroll.current = false;
462
- });
463
- }
464
- }
465
- } else {
466
- const maxScroll = container.scrollHeight - container.clientHeight;
467
- if (maxScroll > 0) {
468
- const target = scrollPosition * maxScroll;
469
- if (Math.abs(container.scrollTop - target) > 1) {
470
- isUpdatingScroll.current = true;
471
- container.scrollTop = target;
472
- requestAnimationFrame(() => {
473
- isUpdatingScroll.current = false;
474
- });
475
- }
476
- }
477
- }
478
- }, [scrollPosition, isHorizontal, scrollRef]);
447
+ if (scrollPosition === void 0 || !container) return;
448
+ const maxScroll = container[axis.size] - container[axis.client];
449
+ if (maxScroll <= 0) return;
450
+ const target = scrollPosition * maxScroll;
451
+ if (Math.abs(container[axis.offset] - target) <= 1) return;
452
+ isUpdatingScroll.current = true;
453
+ container[axis.offset] = target;
454
+ requestAnimationFrame(() => {
455
+ isUpdatingScroll.current = false;
456
+ });
457
+ }, [scrollPosition, axis, scrollRef]);
479
458
  useEffect(() => {
480
- if (!scrollToEnd || hasScrolledToEnd.current) return;
481
459
  const container = scrollRef.current;
482
- if (!container) return;
460
+ if (!scrollToEnd || hasScrolledToEnd.current || !container) return;
483
461
  const timeoutId = setTimeout(() => {
484
- if (isHorizontal) {
485
- container.scrollLeft = container.scrollWidth;
486
- } else {
487
- container.scrollTop = container.scrollHeight;
488
- }
462
+ container[axis.offset] = container[axis.size];
489
463
  hasScrolledToEnd.current = true;
490
464
  }, 100);
491
465
  return () => clearTimeout(timeoutId);
492
- }, [scrollToEnd, isHorizontal, scrollRef, children]);
466
+ }, [scrollToEnd, axis, scrollRef, children]);
493
467
  const defaultOverflowX = isHorizontal ? "auto" : "hidden";
494
468
  const defaultOverflowY = direction === "vertical" || direction === "both" ? "auto" : "hidden";
495
469
  const containerStyle = {
496
- overflowX: style?.overflowX ?? defaultOverflowX,
497
- overflowY: style?.overflowY ?? defaultOverflowY,
498
- ...height !== void 0 ? { height } : {},
499
- ...maxHeight !== void 0 ? { maxHeight } : {},
500
- ...width !== void 0 ? { width } : {},
470
+ overflowX: defaultOverflowX,
471
+ // `style` below overrides these defaults
472
+ overflowY: defaultOverflowY,
473
+ height,
474
+ maxHeight,
475
+ width,
501
476
  ...extendToEdges ? { margin: `-${edgePadding}px`, padding: edgePadding } : {},
502
477
  ...isScrollbarLeft ? { direction: "rtl" } : {},
503
478
  ...style
@@ -534,7 +509,7 @@ function MenuSelect({
534
509
  }) {
535
510
  const [isOpen, setIsOpen] = useState(false);
536
511
  const [focusedIndex, setFocusedIndex] = useState(-1);
537
- const listRef = useRef(null);
512
+ const listboxRef = useRef(null);
538
513
  const selectedOption = options.find((o) => o.value === value);
539
514
  const s = SIZES[size];
540
515
  const handleSelect = useCallback(
@@ -596,13 +571,8 @@ function MenuSelect({
596
571
  [isOpen, focusedIndex, options, handleSelect, handleToggle, findNextEnabled]
597
572
  );
598
573
  useEffect(() => {
599
- if (!isOpen || focusedIndex < 0 || !listRef.current) return;
600
- const listbox = listRef.current.querySelector("[role=listbox]");
601
- if (!listbox) return;
602
- const items = listbox.children;
603
- if (items[focusedIndex]) {
604
- items[focusedIndex].scrollIntoView({ block: "nearest" });
605
- }
574
+ if (!isOpen || focusedIndex < 0) return;
575
+ listboxRef.current?.children[focusedIndex]?.scrollIntoView({ block: "nearest" });
606
576
  }, [isOpen, focusedIndex]);
607
577
  const triggerElement = renderTrigger ? /* @__PURE__ */ jsx(
608
578
  "div",
@@ -697,10 +667,9 @@ function MenuSelect({
697
667
  children: /* @__PURE__ */ jsx(
698
668
  ScrollContainer,
699
669
  {
700
- ref: listRef,
701
670
  direction: "vertical",
702
671
  maxHeight: maxDropdownHeight,
703
- children: /* @__PURE__ */ jsx("div", { role: "listbox", onKeyDown: handleKeyDown, children: options.map((option, index) => {
672
+ children: /* @__PURE__ */ jsx("div", { ref: listboxRef, role: "listbox", onKeyDown: handleKeyDown, children: options.map((option, index) => {
704
673
  const isSelected = option.value === value;
705
674
  const isFocused = index === focusedIndex;
706
675
  const optDisabled = option.isDisabled ?? false;
@@ -763,6 +732,19 @@ function MenuSelect({
763
732
  }
764
733
  );
765
734
  }
735
+ function createItemComparator({
736
+ getVolumeRank,
737
+ statsMap,
738
+ getLabel
739
+ }) {
740
+ return (a, b) => {
741
+ const rankDifference = getVolumeRank ? getVolumeRank(a) - getVolumeRank(b) : 0;
742
+ if (rankDifference !== 0) return rankDifference;
743
+ const countDifference = (statsMap.get(b) ?? 0) - (statsMap.get(a) ?? 0);
744
+ if (countDifference !== 0) return countDifference;
745
+ return getLabel(a).localeCompare(getLabel(b));
746
+ };
747
+ }
766
748
  function MultiSelectFilter({
767
749
  allItems,
768
750
  selectedItems,
@@ -787,23 +769,11 @@ function MultiSelectFilter({
787
769
  () => new Map(itemStats.map((stat) => [stat.item, stat.count])),
788
770
  [itemStats]
789
771
  );
790
- const sortedItems = useMemo(() => {
791
- return Array.from(allItems).sort((a, b) => {
792
- if (getVolumeRank) {
793
- const rankA = getVolumeRank(a);
794
- const rankB = getVolumeRank(b);
795
- if (rankA !== rankB) {
796
- return rankA - rankB;
797
- }
798
- }
799
- const countA = statsMap.get(a) ?? 0;
800
- const countB = statsMap.get(b) ?? 0;
801
- if (countA !== countB) {
802
- return countB - countA;
803
- }
804
- return getLabel(a).localeCompare(getLabel(b));
805
- });
806
- }, [allItems, getVolumeRank, statsMap, getLabel]);
772
+ const compareItems = useMemo(
773
+ () => createItemComparator({ getVolumeRank, statsMap, getLabel }),
774
+ [getVolumeRank, statsMap, getLabel]
775
+ );
776
+ const sortedItems = useMemo(() => Array.from(allItems).sort(compareItems), [allItems, compareItems]);
807
777
  const handleToggle = (item) => {
808
778
  const newSelection = new Set(localSelection);
809
779
  if (newSelection.has(item)) {
@@ -836,22 +806,8 @@ function MultiSelectFilter({
836
806
  if (isShowingAll) {
837
807
  return sortedItems;
838
808
  }
839
- return Array.from(selectedItems).sort((a, b) => {
840
- if (getVolumeRank) {
841
- const rankA = getVolumeRank(a);
842
- const rankB = getVolumeRank(b);
843
- if (rankA !== rankB) {
844
- return rankA - rankB;
845
- }
846
- }
847
- const countA = statsMap.get(a) ?? 0;
848
- const countB = statsMap.get(b) ?? 0;
849
- if (countA !== countB) {
850
- return countB - countA;
851
- }
852
- return getLabel(a).localeCompare(getLabel(b));
853
- });
854
- }, [isShowingAll, sortedItems, selectedItems, getVolumeRank, statsMap, getLabel]);
809
+ return Array.from(selectedItems).sort(compareItems);
810
+ }, [isShowingAll, sortedItems, selectedItems, compareItems]);
855
811
  const iconItems = itemsToDisplay.map((item) => /* @__PURE__ */ jsx(
856
812
  "div",
857
813
  {
@@ -1148,9 +1104,7 @@ function Tooltip({ label, children, isDisabled, placement = "top", display = "in
1148
1104
  useEffect(() => {
1149
1105
  if (!visible) return;
1150
1106
  const onOutsidePointerDown = (event) => {
1151
- if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
1152
- setVisible(false);
1153
- }
1107
+ if (!wrapperRef.current?.contains(event.target)) setVisible(false);
1154
1108
  };
1155
1109
  const onScroll = () => setVisible(false);
1156
1110
  const onKeyDown = (event) => {
@@ -1208,9 +1162,14 @@ function Tooltip({ label, children, isDisabled, placement = "top", display = "in
1208
1162
  }
1209
1163
  );
1210
1164
  }
1165
+ function backgroundForVersion(version, colors) {
1166
+ if (version === "v4") return colors.bgV4 ?? colors.bgV3;
1167
+ if (version === "v3") return colors.bgV3;
1168
+ return colors.bgV2;
1169
+ }
1211
1170
  function VersionBadge(props) {
1212
1171
  const { version, colors, style } = props;
1213
- const bgColor = version === "v4" ? colors.bgV4 ?? colors.bgV3 : version === "v3" ? colors.bgV3 : colors.bgV2;
1172
+ const bgColor = backgroundForVersion(version, colors);
1214
1173
  return /* @__PURE__ */ jsx(
1215
1174
  "span",
1216
1175
  {