@vuu-ui/vuu-popups 0.8.27-debug → 0.8.28-debug

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/esm/index.js CHANGED
@@ -377,12 +377,16 @@ var PopupComponent2 = ({
377
377
  className,
378
378
  anchorElement,
379
379
  minWidth,
380
+ offsetLeft,
381
+ offsetTop,
380
382
  placement,
381
383
  position: positionProp
382
384
  }) => {
383
385
  const { popupRef, position } = useAnchoredPosition({
384
386
  anchorElement,
385
387
  minWidth,
388
+ offsetLeft,
389
+ offsetTop,
386
390
  placement,
387
391
  position: positionProp
388
392
  });
@@ -926,6 +930,7 @@ var MenuList = ({
926
930
  const hasSubMenu = isMenuItemGroup(child);
927
931
  const subMenuShowing = hasSubMenu && childMenuShowing === itemId;
928
932
  const ariaControls = subMenuShowing ? `${id}-${itemId}` : void 0;
933
+ const ariaLabel = (label != null ? label : typeof children2 === "string") ? children2 : void 0;
929
934
  list.push(
930
935
  /* @__PURE__ */ jsx5(
931
936
  MenuItem,
@@ -944,6 +949,7 @@ var MenuList = ({
944
949
  "aria-controls": ariaControls,
945
950
  "aria-haspopup": hasSubMenu || void 0,
946
951
  "aria-expanded": subMenuShowing || void 0,
952
+ "aria-label": ariaLabel,
947
953
  children: hasSubMenu ? maybeIcon(label != null ? label : children2, withIcon, iconName) : maybeIcon(children2, withIcon, iconName)
948
954
  }
949
955
  )
@@ -1844,24 +1850,19 @@ var Prompt = ({
1844
1850
  };
1845
1851
 
1846
1852
  // src/tooltip/useAnchoredPosition.ts
1847
- import { useLayoutEffect as useLayoutEffect6, useState as useState7 } from "react";
1848
- var getPositionRelativeToAnchor2 = (anchorElement, placement, offsetLeft, offsetTop) => {
1849
- const { bottom, height, left, right, top, width } = anchorElement.getBoundingClientRect();
1850
- const midX = left + width / 2;
1851
- const midY = top + height / 2;
1852
- switch (placement) {
1853
- case "above":
1854
- return { left: midX + offsetLeft, top: top + offsetTop };
1855
- case "below":
1856
- return { left: midX + offsetLeft, top: bottom + offsetTop };
1857
- case "right":
1858
- return { left: right + offsetLeft, top: midY + offsetLeft };
1859
- case "left":
1860
- return { left: left + offsetLeft, top: midY + offsetLeft };
1861
- default:
1862
- throw Error(
1863
- "Tooltip getPositionRelativeToAnchor only supported placement values are left, right, below and right"
1864
- );
1853
+ import { useCallback as useCallback11, useLayoutEffect as useLayoutEffect6 } from "react";
1854
+ var pointerSize = 12;
1855
+ var roomAbove = (anchor, height) => height < anchor.top;
1856
+ var roomBelow = (anchor, height) => document.body.clientHeight - anchor.bottom > height;
1857
+ var getNextPlacement = (placement) => {
1858
+ if (Array.isArray(placement)) {
1859
+ if (placement.length === 0) {
1860
+ return [void 0, placement];
1861
+ } else {
1862
+ return [placement[0], placement.slice(1)];
1863
+ }
1864
+ } else {
1865
+ return [placement, []];
1865
1866
  }
1866
1867
  };
1867
1868
  var useAnchoredPosition2 = ({
@@ -1870,19 +1871,49 @@ var useAnchoredPosition2 = ({
1870
1871
  offsetTop = 0,
1871
1872
  placement
1872
1873
  }) => {
1873
- const [position, setPosition] = useState7();
1874
+ const ref = useCallback11(
1875
+ (el) => {
1876
+ if (el && anchorElement.current) {
1877
+ const anchor = anchorElement.current.getBoundingClientRect();
1878
+ const { height, width } = el.getBoundingClientRect();
1879
+ let nextPlacement;
1880
+ let placements = placement;
1881
+ do {
1882
+ [nextPlacement, placements] = getNextPlacement(placements);
1883
+ switch (nextPlacement) {
1884
+ case "above":
1885
+ if (roomAbove(anchor, height + pointerSize)) {
1886
+ const midDiff = (width - anchor.width) / 2;
1887
+ el.style.cssText = `left:${anchor.left - midDiff}px;top:${anchor.top - height - pointerSize}px;opacity: 1;`;
1888
+ el.dataset.align = "above";
1889
+ return;
1890
+ }
1891
+ break;
1892
+ case "below":
1893
+ if (roomBelow(anchor, height + pointerSize)) {
1894
+ const midDiff = (width - anchor.width) / 2;
1895
+ el.style.cssText = `left:${anchor.left - midDiff}px;top:${anchor.bottom + pointerSize}px;opacity: 1;`;
1896
+ el.dataset.align = "below";
1897
+ return;
1898
+ }
1899
+ break;
1900
+ case "right":
1901
+ console.log("place the fucker right");
1902
+ break;
1903
+ case "left":
1904
+ console.log("place the fucker left");
1905
+ break;
1906
+ default:
1907
+ console.warn(`unklnown tooltip placement ${placement}`);
1908
+ }
1909
+ } while (nextPlacement);
1910
+ }
1911
+ },
1912
+ [anchorElement, placement]
1913
+ );
1874
1914
  useLayoutEffect6(() => {
1875
- if (anchorElement.current) {
1876
- const position2 = getPositionRelativeToAnchor2(
1877
- anchorElement.current,
1878
- placement,
1879
- offsetLeft,
1880
- offsetTop
1881
- );
1882
- setPosition(position2);
1883
- }
1884
1915
  }, [anchorElement, offsetLeft, offsetTop, placement]);
1885
- return position;
1916
+ return ref;
1886
1917
  };
1887
1918
 
1888
1919
  // src/tooltip/Tooltip.tsx
@@ -1892,26 +1923,27 @@ var classBase6 = "vuuTooltip";
1892
1923
  var Tooltip = ({
1893
1924
  anchorElement,
1894
1925
  children,
1926
+ className,
1895
1927
  id,
1896
1928
  onMouseEnter,
1897
1929
  onMouseLeave,
1898
- placement,
1930
+ placement: placementProp,
1899
1931
  status,
1900
1932
  style: styleProp
1901
1933
  }) => {
1902
- const position = useAnchoredPosition2({ anchorElement, placement });
1903
- if (position === void 0) {
1904
- return null;
1905
- }
1934
+ const ref = useAnchoredPosition2({
1935
+ anchorElement,
1936
+ placement: placementProp
1937
+ });
1906
1938
  return /* @__PURE__ */ jsx11(Portal, { children: /* @__PURE__ */ jsx11(
1907
1939
  "div",
1908
1940
  {
1909
- className: cx9(classBase6, {
1941
+ className: cx9(classBase6, className, "vuuHidden", {
1910
1942
  [`${classBase6}-error`]: status === "error"
1911
1943
  }),
1912
- "data-align": placement,
1913
1944
  id,
1914
- style: { ...styleProp, ...position },
1945
+ ref,
1946
+ style: { ...styleProp, left: 0, top: 0 },
1915
1947
  children: /* @__PURE__ */ jsx11(
1916
1948
  "span",
1917
1949
  {
@@ -1926,82 +1958,96 @@ var Tooltip = ({
1926
1958
  };
1927
1959
 
1928
1960
  // src/tooltip/useTooltip.ts
1929
- import { useId as useId4 } from "@vuu-ui/vuu-utils";
1930
- import { useCallback as useCallback11, useRef as useRef10, useState as useState8 } from "react";
1961
+ import { queryClosest, useId as useId4 } from "@vuu-ui/vuu-utils";
1962
+ import { useCallback as useCallback12, useRef as useRef10, useState as useState7 } from "react";
1931
1963
  var useTooltip = ({
1964
+ anchorQuery = "*",
1932
1965
  id: idProp,
1933
1966
  placement = "right",
1934
1967
  tooltipContent
1935
1968
  }) => {
1936
1969
  const hideTooltipRef = useRef10();
1970
+ const isHoveringRef = useRef10(false);
1937
1971
  const anchorElementRef = useRef10(null);
1938
1972
  const mouseEnterTimerRef = useRef10();
1939
1973
  const mouseLeaveTimerRef = useRef10();
1940
- const [tooltipProps, setTooltipProps] = useState8();
1974
+ const [tooltipProps, setTooltipProps] = useState7();
1941
1975
  const id = useId4(idProp);
1942
- const escapeListener = useCallback11((evt) => {
1976
+ const escapeListener = useCallback12((evt) => {
1943
1977
  var _a;
1944
1978
  if (evt.key === "Escape") {
1945
1979
  (_a = hideTooltipRef.current) == null ? void 0 : _a.call(hideTooltipRef);
1946
1980
  }
1947
1981
  }, []);
1948
- hideTooltipRef.current = useCallback11(() => {
1982
+ hideTooltipRef.current = useCallback12(() => {
1949
1983
  setTooltipProps(void 0);
1950
1984
  document.removeEventListener("keydown", escapeListener);
1951
1985
  }, [escapeListener]);
1952
- const handleMouseEnterTooltip = useCallback11(() => {
1986
+ const handleMouseEnterTooltip = useCallback12(() => {
1953
1987
  window.clearTimeout(mouseLeaveTimerRef.current);
1954
1988
  }, []);
1955
- const handleMouseLeaveTooltip = useCallback11(() => {
1989
+ const handleMouseLeaveTooltip = useCallback12(() => {
1956
1990
  var _a;
1957
1991
  (_a = hideTooltipRef.current) == null ? void 0 : _a.call(hideTooltipRef);
1958
1992
  }, []);
1959
- const showTooltip = useCallback11(() => {
1960
- const { current: anchorEl } = anchorElementRef;
1961
- if (anchorEl) {
1962
- setTooltipProps({
1963
- anchorElement: anchorElementRef,
1964
- children: tooltipContent,
1965
- id: `${id}-tooltip`,
1966
- onMouseEnter: handleMouseEnterTooltip,
1967
- onMouseLeave: handleMouseLeaveTooltip,
1968
- placement
1969
- });
1970
- document.addEventListener("keydown", escapeListener);
1993
+ const hideTooltip = useCallback12((defer = 0) => {
1994
+ if (mouseEnterTimerRef.current) {
1995
+ window.clearTimeout(mouseEnterTimerRef.current);
1996
+ mouseEnterTimerRef.current = void 0;
1997
+ } else if (hideTooltipRef.current) {
1998
+ if (defer === 0) {
1999
+ hideTooltipRef.current();
2000
+ } else {
2001
+ mouseLeaveTimerRef.current = window.setTimeout(
2002
+ hideTooltipRef.current,
2003
+ defer
2004
+ );
2005
+ }
1971
2006
  }
1972
- mouseEnterTimerRef.current = void 0;
1973
- }, [
1974
- escapeListener,
1975
- handleMouseEnterTooltip,
1976
- handleMouseLeaveTooltip,
1977
- id,
1978
- placement,
1979
- tooltipContent
1980
- ]);
1981
- const handleMouseEnter = useCallback11(
2007
+ }, []);
2008
+ const showTooltip = useCallback12(
2009
+ (ref = anchorElementRef) => {
2010
+ const { current: anchorEl } = ref;
2011
+ if (anchorEl) {
2012
+ setTooltipProps({
2013
+ anchorElement: ref,
2014
+ children: tooltipContent,
2015
+ id: `${id}-tooltip`,
2016
+ onMouseEnter: handleMouseEnterTooltip,
2017
+ onMouseLeave: handleMouseLeaveTooltip,
2018
+ placement
2019
+ });
2020
+ document.addEventListener("keydown", escapeListener);
2021
+ }
2022
+ mouseEnterTimerRef.current = void 0;
2023
+ hideTooltip(isHoveringRef.current ? 3e3 : 1e3);
2024
+ },
2025
+ [
2026
+ escapeListener,
2027
+ handleMouseEnterTooltip,
2028
+ handleMouseLeaveTooltip,
2029
+ hideTooltip,
2030
+ id,
2031
+ placement,
2032
+ tooltipContent
2033
+ ]
2034
+ );
2035
+ const handleMouseEnter = useCallback12(
1982
2036
  (evt) => {
1983
- const el = evt.target;
2037
+ isHoveringRef.current = true;
2038
+ const el = queryClosest(evt.target, anchorQuery);
1984
2039
  if (el) {
2040
+ console.log(`el ${el.classList}`);
1985
2041
  anchorElementRef.current = el;
1986
2042
  mouseEnterTimerRef.current = window.setTimeout(showTooltip, 800);
1987
2043
  }
1988
2044
  },
1989
- [showTooltip]
2045
+ [anchorQuery, showTooltip]
1990
2046
  );
1991
- const handleMouseLeave = useCallback11(() => {
1992
- if (anchorElementRef.current)
1993
- if (mouseEnterTimerRef.current) {
1994
- window.clearTimeout(mouseEnterTimerRef.current);
1995
- mouseEnterTimerRef.current = void 0;
1996
- } else {
1997
- if (hideTooltipRef.current) {
1998
- mouseLeaveTimerRef.current = window.setTimeout(
1999
- hideTooltipRef.current,
2000
- 200
2001
- );
2002
- }
2003
- }
2004
- }, []);
2047
+ const handleMouseLeave = useCallback12(() => {
2048
+ isHoveringRef.current = false;
2049
+ hideTooltip(200);
2050
+ }, [hideTooltip]);
2005
2051
  const anchorProps = {
2006
2052
  "aria-describedby": `${id}-tooltip`,
2007
2053
  onMouseEnter: handleMouseEnter,
@@ -2009,12 +2055,14 @@ var useTooltip = ({
2009
2055
  };
2010
2056
  return {
2011
2057
  anchorProps,
2058
+ hideTooltip,
2059
+ showTooltip,
2012
2060
  tooltipProps
2013
2061
  };
2014
2062
  };
2015
2063
 
2016
2064
  // src/notifications/NotificationsProvider.tsx
2017
- import React4, { useState as useState9, useContext as useContext2, useCallback as useCallback12, useEffect } from "react";
2065
+ import React4, { useState as useState8, useContext as useContext2, useCallback as useCallback13, useEffect } from "react";
2018
2066
  import classNames from "clsx";
2019
2067
  import { getUniqueId } from "@vuu-ui/vuu-utils";
2020
2068
  import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
@@ -2039,8 +2087,8 @@ var NotificationsContext = React4.createContext({
2039
2087
  notify: () => "have you forgotten to provide a NotificationProvider?"
2040
2088
  });
2041
2089
  var NotificationsProvider = (props) => {
2042
- const [notifications, setNotifications] = useState9([]);
2043
- const notify = useCallback12((notification) => {
2090
+ const [notifications, setNotifications] = useState8([]);
2091
+ const notify = useCallback13((notification) => {
2044
2092
  const newNotification = { ...notification, id: getUniqueId() };
2045
2093
  setNotifications((prev) => [...prev, newNotification]);
2046
2094
  setTimeout(() => {
@@ -2070,7 +2118,7 @@ var NotificationsProvider = (props) => {
2070
2118
  var useNotifications = () => useContext2(NotificationsContext);
2071
2119
  var ToastNotification = (props) => {
2072
2120
  const { top, notification, animated = true } = props;
2073
- const [right, setRight] = useState9(-toastWidth - toastContainerRightPadding);
2121
+ const [right, setRight] = useState8(-toastWidth - toastContainerRightPadding);
2074
2122
  useEffect(() => {
2075
2123
  setTimeout(() => setRight(toastContainerRightPadding));
2076
2124
  if (animated) {