@sanity/ui 1.7.12 → 1.8.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
@@ -3074,9 +3074,9 @@ function getGlobalScope() {
3074
3074
  throw new Error("@sanity/ui: could not locate global scope");
3075
3075
  }
3076
3076
  const globalScope = getGlobalScope();
3077
- const key$7 = Symbol.for("@sanity/ui/context/theme");
3078
- globalScope[key$7] = globalScope[key$7] || react.createContext(null);
3079
- const ThemeContext = globalScope[key$7];
3077
+ const key$8 = Symbol.for("@sanity/ui/context/theme");
3078
+ globalScope[key$8] = globalScope[key$8] || react.createContext(null);
3079
+ const ThemeContext = globalScope[key$8];
3080
3080
  function ThemeProvider(props) {
3081
3081
  const parentTheme = react.useContext(ThemeContext);
3082
3082
  const {
@@ -5269,9 +5269,9 @@ const KBD = react.forwardRef(function KBD2(props, ref) {
5269
5269
  })
5270
5270
  });
5271
5271
  });
5272
- const key$6 = Symbol.for("@sanity/ui/context/boundaryElement");
5273
- globalScope[key$6] = globalScope[key$6] || react.createContext(null);
5274
- const BoundaryElementContext = globalScope[key$6];
5272
+ const key$7 = Symbol.for("@sanity/ui/context/boundaryElement");
5273
+ globalScope[key$7] = globalScope[key$7] || react.createContext(null);
5274
+ const BoundaryElementContext = globalScope[key$7];
5275
5275
  function BoundaryElementProvider(props) {
5276
5276
  const {
5277
5277
  children,
@@ -5400,9 +5400,9 @@ function getLayerContext(contextValue) {
5400
5400
  }
5401
5401
  throw new Error("could not get layer context");
5402
5402
  }
5403
- const key$5 = Symbol.for("@sanity/ui/context/layer");
5404
- globalScope[key$5] = globalScope[key$5] || react.createContext(null);
5405
- const LayerContext = globalScope[key$5];
5403
+ const key$6 = Symbol.for("@sanity/ui/context/layer");
5404
+ globalScope[key$6] = globalScope[key$6] || react.createContext(null);
5405
+ const LayerContext = globalScope[key$6];
5406
5406
  function useLayer() {
5407
5407
  const value = react.useContext(LayerContext);
5408
5408
  if (!value) {
@@ -5639,7 +5639,7 @@ const Layer = react.forwardRef(function Layer2(props, ref) {
5639
5639
  })
5640
5640
  });
5641
5641
  });
5642
- const key$4 = Symbol.for("@sanity/ui/context/portal");
5642
+ const key$5 = Symbol.for("@sanity/ui/context/portal");
5643
5643
  const elementKey = Symbol.for("@sanity/ui/context/portal/element");
5644
5644
  globalScope[elementKey] = null;
5645
5645
  const defaultContextValue = {
@@ -5658,8 +5658,8 @@ const defaultContextValue = {
5658
5658
  return globalScope[elementKey];
5659
5659
  }
5660
5660
  };
5661
- globalScope[key$4] = globalScope[key$4] || react.createContext(defaultContextValue);
5662
- const PortalContext = globalScope[key$4];
5661
+ globalScope[key$5] = globalScope[key$5] || react.createContext(defaultContextValue);
5662
+ const PortalContext = globalScope[key$5];
5663
5663
  function usePortal() {
5664
5664
  const value = react.useContext(PortalContext);
5665
5665
  if (!value) {
@@ -6825,6 +6825,22 @@ const TextInput = react.forwardRef(function TextInput2(props, forwardedRef) {
6825
6825
  }), suffixNode]
6826
6826
  });
6827
6827
  });
6828
+ function useDelayedState(initialState) {
6829
+ const [state, setState] = react.useState(initialState);
6830
+ const delayedAction = react.useRef();
6831
+ const onStateChange = react.useCallback((nextState, delay) => {
6832
+ const action = () => {
6833
+ setState(nextState);
6834
+ };
6835
+ if (delayedAction.current) {
6836
+ clearTimeout(delayedAction.current);
6837
+ delayedAction.current = void 0;
6838
+ }
6839
+ if (!delay) return action();
6840
+ delayedAction.current = setTimeout(action, delay);
6841
+ }, []);
6842
+ return [state, onStateChange];
6843
+ }
6828
6844
  var __freeze$f = Object.freeze;
6829
6845
  var __defProp$f = Object.defineProperty;
6830
6846
  var __template$f = (cooked, raw) => __freeze$f(__defProp$f(cooked, "raw", {
@@ -6854,6 +6870,40 @@ const TooltipArrow = react.forwardRef(function TooltipArrow2(props, ref) {
6854
6870
  })
6855
6871
  });
6856
6872
  });
6873
+ const key$4 = Symbol.for("@sanity/ui/context/tooltipDelayGroup");
6874
+ globalScope[key$4] = globalScope[key$4] || react.createContext(null);
6875
+ const TooltipDelayGroupContext = globalScope[key$4];
6876
+ function useTooltipDelayGroup() {
6877
+ const value = react.useContext(TooltipDelayGroupContext);
6878
+ return value;
6879
+ }
6880
+ function TooltipDelayGroupProvider(props) {
6881
+ const {
6882
+ children,
6883
+ delay
6884
+ } = props;
6885
+ const [isGroupActive, setIsGroupActive] = useDelayedState(false);
6886
+ const [openTooltipId, setOpenTooltipId] = useDelayedState(null);
6887
+ const isInsideContext = useTooltipDelayGroup();
6888
+ if (isInsideContext) {
6889
+ throw new Error("TooltipDelayGroupProvider cannot be nested inside another TooltipDelayGroupProvider");
6890
+ }
6891
+ const openDelay = typeof delay === "number" ? delay : (delay == null ? void 0 : delay.open) || 0;
6892
+ const closeDelay = typeof delay === "number" ? delay : (delay == null ? void 0 : delay.close) || 0;
6893
+ const value = react.useMemo(() => ({
6894
+ isGroupActive,
6895
+ setIsGroupActive,
6896
+ openTooltipId,
6897
+ setOpenTooltipId,
6898
+ // When the group is active, we want the next tooltip to open immediately.
6899
+ openDelay: isGroupActive ? 1 : openDelay,
6900
+ closeDelay
6901
+ }), [closeDelay, isGroupActive, openDelay, openTooltipId, setIsGroupActive, setOpenTooltipId]);
6902
+ return /* @__PURE__ */jsxRuntime.jsx(TooltipDelayGroupContext.Provider, {
6903
+ value,
6904
+ children
6905
+ });
6906
+ }
6857
6907
  var __freeze$e = Object.freeze;
6858
6908
  var __defProp$e = Object.defineProperty;
6859
6909
  var __template$e = (cooked, raw) => __freeze$e(__defProp$e(cooked, "raw", {
@@ -6877,6 +6927,7 @@ const Tooltip = react.forwardRef(function Tooltip2(props, ref) {
6877
6927
  scheme,
6878
6928
  shadow = 2,
6879
6929
  zOffset = (_a2 = theme.sanity.layer) == null ? void 0 : _a2.tooltip.zOffset,
6930
+ delay,
6880
6931
  ...restProps
6881
6932
  } = props;
6882
6933
  const fallbackPlacements = useArrayProp(fallbackPlacementsProp);
@@ -6947,18 +6998,41 @@ const Tooltip = react.forwardRef(function Tooltip2(props, ref) {
6947
6998
  if (staticSide) style[staticSide] = -15;
6948
6999
  return style;
6949
7000
  }, [arrowX, arrowY, staticSide]);
6950
- const [isOpen, setIsOpen] = react.useState(false);
6951
- const handleBlur = react.useCallback(() => setIsOpen(false), []);
6952
- const handleFocus = react.useCallback(() => setIsOpen(true), []);
6953
- const handleMouseEnter = react.useCallback(() => setIsOpen(true), []);
6954
- const handleMouseLeave = react.useCallback(() => setIsOpen(false), []);
7001
+ const tooltipId = react.useId();
7002
+ const [isOpen, setIsOpen] = useDelayedState(false);
7003
+ const delayGroupContext = useTooltipDelayGroup();
7004
+ const showTooltip = isOpen || (delayGroupContext == null ? void 0 : delayGroupContext.openTooltipId) === tooltipId;
7005
+ const isInsideGroup = delayGroupContext !== null;
7006
+ const openDelayProp = typeof delay === "number" ? delay : (delay == null ? void 0 : delay.open) || 0;
7007
+ const closeDelayProp = typeof delay === "number" ? delay : (delay == null ? void 0 : delay.close) || 0;
7008
+ const openDelay = isInsideGroup ? delayGroupContext.openDelay : openDelayProp;
7009
+ const closeDelay = isInsideGroup ? delayGroupContext.closeDelay : closeDelayProp;
7010
+ const handleIsOpenChange = react.useCallback(open => {
7011
+ if (isInsideGroup) {
7012
+ if (open) {
7013
+ delayGroupContext.setIsGroupActive(open, openDelay);
7014
+ delayGroupContext.setOpenTooltipId(tooltipId, openDelay);
7015
+ } else {
7016
+ const minimumGroupDeactivateDelay = 200;
7017
+ const groupDeactivateDelay = closeDelay > minimumGroupDeactivateDelay ? closeDelay : minimumGroupDeactivateDelay;
7018
+ delayGroupContext.setIsGroupActive(open, groupDeactivateDelay);
7019
+ delayGroupContext.setOpenTooltipId(null, closeDelay);
7020
+ }
7021
+ } else {
7022
+ setIsOpen(open, open ? openDelay : closeDelay);
7023
+ }
7024
+ }, [isInsideGroup, delayGroupContext, openDelay, tooltipId, closeDelay, setIsOpen]);
7025
+ const handleBlur = react.useCallback(() => handleIsOpenChange(false), [handleIsOpenChange]);
7026
+ const handleFocus = react.useCallback(() => handleIsOpenChange(true), [handleIsOpenChange]);
7027
+ const handleMouseEnter = react.useCallback(() => handleIsOpenChange(true), [handleIsOpenChange]);
7028
+ const handleMouseLeave = react.useCallback(() => handleIsOpenChange(false), [handleIsOpenChange]);
6955
7029
  react.useEffect(() => {
6956
7030
  if (!isOpen) return;
6957
7031
  function handleWindowMouseMove(event) {
6958
7032
  if (!referenceElement) return;
6959
7033
  const isHoveringReference = referenceElement === event.target || event.target instanceof Node && referenceElement.contains(event.target);
6960
7034
  if (!isHoveringReference) {
6961
- setIsOpen(false);
7035
+ handleIsOpenChange(false);
6962
7036
  window.removeEventListener("mousemove", handleWindowMouseMove);
6963
7037
  }
6964
7038
  }
@@ -6966,13 +7040,13 @@ const Tooltip = react.forwardRef(function Tooltip2(props, ref) {
6966
7040
  return () => {
6967
7041
  window.removeEventListener("mousemove", handleWindowMouseMove);
6968
7042
  };
6969
- }, [isOpen, referenceElement]);
7043
+ }, [isOpen, referenceElement, handleIsOpenChange]);
6970
7044
  react.useEffect(() => {
6971
- if (disabled) setIsOpen(false);
6972
- }, [disabled]);
7045
+ if (disabled) handleIsOpenChange(false);
7046
+ }, [disabled, handleIsOpenChange]);
6973
7047
  react.useEffect(() => {
6974
- if (!content) setIsOpen(false);
6975
- }, [content]);
7048
+ if (!content) handleIsOpenChange(false);
7049
+ }, [content, handleIsOpenChange]);
6976
7050
  react.useEffect(() => refs.setReference(referenceElement), [referenceElement, refs]);
6977
7051
  const setArrow = react.useCallback(arrowEl => {
6978
7052
  arrowRef.current = arrowEl;
@@ -7023,7 +7097,7 @@ const Tooltip = react.forwardRef(function Tooltip2(props, ref) {
7023
7097
  })
7024
7098
  });
7025
7099
  return /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
7026
- children: [child, isOpen && /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
7100
+ children: [child, showTooltip && /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
7027
7101
  children: portal ? /* @__PURE__ */jsxRuntime.jsx(Portal, {
7028
7102
  __unstable_name: typeof portal === "string" ? portal : void 0,
7029
7103
  children: root
@@ -9659,6 +9733,8 @@ exports.ThemeProvider = ThemeProvider;
9659
9733
  exports.Toast = Toast;
9660
9734
  exports.ToastProvider = ToastProvider;
9661
9735
  exports.Tooltip = Tooltip;
9736
+ exports.TooltipDelayGroupContext = TooltipDelayGroupContext;
9737
+ exports.TooltipDelayGroupProvider = TooltipDelayGroupProvider;
9662
9738
  exports.Tree = Tree;
9663
9739
  exports.TreeItem = TreeItem;
9664
9740
  exports.VirtualList = VirtualList;
@@ -9717,5 +9793,6 @@ exports.usePrefersReducedMotion = usePrefersReducedMotion;
9717
9793
  exports.useRootTheme = useRootTheme;
9718
9794
  exports.useTheme = useTheme;
9719
9795
  exports.useToast = useToast;
9796
+ exports.useTooltipDelayGroup = useTooltipDelayGroup;
9720
9797
  exports.useTree = useTree;
9721
9798
  //# sourceMappingURL=index.js.map