@sanity/ui 2.7.1-canary.0 → 2.7.1-canary.2

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.d.mts CHANGED
@@ -625,6 +625,11 @@ export declare interface CheckboxProps {
625
625
  customValidity?: string
626
626
  }
627
627
 
628
+ /**
629
+ * @public
630
+ */
631
+ export declare type ClickOutsideElements = (HTMLElement | null | (HTMLElement | null)[])[]
632
+
628
633
  /**
629
634
  * @public
630
635
  */
@@ -2652,10 +2657,69 @@ export declare function useBoundaryElement(): BoundaryElementContextValue
2652
2657
  * @public
2653
2658
  */
2654
2659
  export declare function useClickOutside(
2655
- listener: ClickOutsideListener,
2656
- elementsArg?: Array<HTMLElement | HTMLElement[] | null>,
2660
+ listener: ClickOutsideListener | false | undefined,
2661
+ elementsArg: () => ClickOutsideElements,
2662
+ boundaryElement?: () => HTMLElement | null,
2663
+ ): void
2664
+
2665
+ /**
2666
+ * @public
2667
+ * @deprecated - change `useClickOutside(handler, () => [...], boundary)` to `useClickOutside(handler, () => [...], () => boundary)`
2668
+ */
2669
+ export declare function useClickOutside(
2670
+ listener: ClickOutsideListener | false | undefined,
2671
+ elementsArg: () => ClickOutsideElements,
2672
+ boundaryElement: HTMLElement | null,
2673
+ ): void
2674
+
2675
+ /**
2676
+ * @public
2677
+ * @deprecated - change `useClickOutside(handler, [...], () => boundary)` to `useClickOutside(handler, () => [...], () => boundary)`
2678
+ */
2679
+ export declare function useClickOutside(
2680
+ listener: ClickOutsideListener | false | undefined,
2681
+ elementsArg: ClickOutsideElements,
2682
+ boundaryElement: () => HTMLElement | null,
2683
+ ): UseClickOutsideSetElement
2684
+
2685
+ /**
2686
+ * @public
2687
+ * @deprecated
2688
+ * Instead of:
2689
+ * ```tsx
2690
+ * const buttonRef = useRef(null)
2691
+ * const setElement = useClickOutside(() => {}, [buttonRef.current])
2692
+ * return (
2693
+ * <>
2694
+ * <button ref={buttonRef} />
2695
+ * {open && <div ref={setElement} />}
2696
+ * </>
2697
+ * )
2698
+ * ```
2699
+ * Use:
2700
+ * ```tsx
2701
+ * const buttonRef = useRef()
2702
+ * const [element, setElement] = useState(null)
2703
+ * useClickOutside(() => {}, () => [buttonRef.current, element])
2704
+ * return (
2705
+ * <>
2706
+ * <button ref={buttonRef} />
2707
+ * {open && <div ref={setElement} />}
2708
+ * </>
2709
+ * )
2710
+ * ```
2711
+ */
2712
+ export declare function useClickOutside(
2713
+ listener: ClickOutsideListener | false | undefined,
2714
+ elementsArg: ClickOutsideElements,
2657
2715
  boundaryElement?: HTMLElement | null,
2658
- ): (el: HTMLElement | null) => void
2716
+ ): UseClickOutsideSetElement
2717
+
2718
+ /**
2719
+ * @public
2720
+ * @deprecated - use your own `const [element, setElement] = useState(null)` logic instead
2721
+ */
2722
+ export declare type UseClickOutsideSetElement = (el: HTMLElement | null) => void
2659
2723
 
2660
2724
  /**
2661
2725
  * @beta
package/dist/index.d.ts CHANGED
@@ -625,6 +625,11 @@ export declare interface CheckboxProps {
625
625
  customValidity?: string
626
626
  }
627
627
 
628
+ /**
629
+ * @public
630
+ */
631
+ export declare type ClickOutsideElements = (HTMLElement | null | (HTMLElement | null)[])[]
632
+
628
633
  /**
629
634
  * @public
630
635
  */
@@ -2652,10 +2657,69 @@ export declare function useBoundaryElement(): BoundaryElementContextValue
2652
2657
  * @public
2653
2658
  */
2654
2659
  export declare function useClickOutside(
2655
- listener: ClickOutsideListener,
2656
- elementsArg?: Array<HTMLElement | HTMLElement[] | null>,
2660
+ listener: ClickOutsideListener | false | undefined,
2661
+ elementsArg: () => ClickOutsideElements,
2662
+ boundaryElement?: () => HTMLElement | null,
2663
+ ): void
2664
+
2665
+ /**
2666
+ * @public
2667
+ * @deprecated - change `useClickOutside(handler, () => [...], boundary)` to `useClickOutside(handler, () => [...], () => boundary)`
2668
+ */
2669
+ export declare function useClickOutside(
2670
+ listener: ClickOutsideListener | false | undefined,
2671
+ elementsArg: () => ClickOutsideElements,
2672
+ boundaryElement: HTMLElement | null,
2673
+ ): void
2674
+
2675
+ /**
2676
+ * @public
2677
+ * @deprecated - change `useClickOutside(handler, [...], () => boundary)` to `useClickOutside(handler, () => [...], () => boundary)`
2678
+ */
2679
+ export declare function useClickOutside(
2680
+ listener: ClickOutsideListener | false | undefined,
2681
+ elementsArg: ClickOutsideElements,
2682
+ boundaryElement: () => HTMLElement | null,
2683
+ ): UseClickOutsideSetElement
2684
+
2685
+ /**
2686
+ * @public
2687
+ * @deprecated
2688
+ * Instead of:
2689
+ * ```tsx
2690
+ * const buttonRef = useRef(null)
2691
+ * const setElement = useClickOutside(() => {}, [buttonRef.current])
2692
+ * return (
2693
+ * <>
2694
+ * <button ref={buttonRef} />
2695
+ * {open && <div ref={setElement} />}
2696
+ * </>
2697
+ * )
2698
+ * ```
2699
+ * Use:
2700
+ * ```tsx
2701
+ * const buttonRef = useRef()
2702
+ * const [element, setElement] = useState(null)
2703
+ * useClickOutside(() => {}, () => [buttonRef.current, element])
2704
+ * return (
2705
+ * <>
2706
+ * <button ref={buttonRef} />
2707
+ * {open && <div ref={setElement} />}
2708
+ * </>
2709
+ * )
2710
+ * ```
2711
+ */
2712
+ export declare function useClickOutside(
2713
+ listener: ClickOutsideListener | false | undefined,
2714
+ elementsArg: ClickOutsideElements,
2657
2715
  boundaryElement?: HTMLElement | null,
2658
- ): (el: HTMLElement | null) => void
2716
+ ): UseClickOutsideSetElement
2717
+
2718
+ /**
2719
+ * @public
2720
+ * @deprecated - use your own `const [element, setElement] = useState(null)` logic instead
2721
+ */
2722
+ export declare type UseClickOutsideSetElement = (el: HTMLElement | null) => void
2659
2723
 
2660
2724
  /**
2661
2725
  * @beta
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { buildTheme, createColorTheme as createColorTheme$1, hexToRgb as hexToRgb$1, hslToRgb as hslToRgb$1, multiply as multiply$1, parseColor as parseColor$1, rgbToHex as rgbToHex$1, rgbToHsl as rgbToHsl$1, rgba as rgba$1, screen as screen$1, getTheme_v2, getScopedTheme } from "@sanity/ui/theme";
2
2
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
- import { useMemo, useState, useRef, useEffect, useImperativeHandle, useDebugValue, useSyncExternalStore, createContext, useContext, forwardRef, useId, useCallback, Children, isValidElement, cloneElement, Component, memo, useLayoutEffect, useReducer, Fragment as Fragment$1, startTransition } from "react";
3
+ import { useMemo, useState, useEffect, useRef, useImperativeHandle, useDebugValue, useSyncExternalStore, createContext, useContext, forwardRef, useId, useCallback, Children, isValidElement, cloneElement, Component, memo, useLayoutEffect, useReducer, Fragment as Fragment$1, startTransition } from "react";
4
4
  import ReactIs, { isValidElementType } from "react-is";
5
5
  import { ThemeProvider as ThemeProvider$1, useTheme as useTheme$1, css, styled, keyframes } from "styled-components";
6
6
  import { SpinnerIcon, CheckmarkIcon, RemoveIcon, ChevronDownIcon, CloseIcon, ChevronRightIcon, ToggleArrowRightIcon } from "@sanity/icons";
@@ -131,45 +131,30 @@ function useArrayProp(val, defaultVal) {
131
131
  [__perf_hash__]
132
132
  );
133
133
  }
134
- function _getElements(element, elementsArg) {
135
- const ret = [element];
136
- for (const el of elementsArg)
137
- Array.isArray(el) ? ret.push(...el) : ret.push(el);
138
- return ret.filter(Boolean);
139
- }
140
134
  function useClickOutside(listener, elementsArg = EMPTY_ARRAY, boundaryElement) {
141
- const [element, setElement] = useState(null), [elements, setElements] = useState(() => _getElements(element, elementsArg)), elementsRef = useRef(elements);
142
- return useEffect(() => {
143
- const prevElements = elementsRef.current, nextElements = _getElements(element, elementsArg);
144
- if (prevElements.length !== nextElements.length) {
145
- setElements(nextElements), elementsRef.current = nextElements;
135
+ const [legacyElement, setLegacyElement] = useState(null), onEvent = useEffectEvent((evt) => {
136
+ if (!listener)
146
137
  return;
147
- }
148
- for (const el of prevElements)
149
- if (!nextElements.includes(el)) {
150
- setElements(nextElements), elementsRef.current = nextElements;
151
- return;
152
- }
153
- for (const el of nextElements)
154
- if (!prevElements.includes(el)) {
155
- setElements(nextElements), elementsRef.current = nextElements;
138
+ const target = evt.target;
139
+ if (!(target instanceof Node))
140
+ return;
141
+ const resolvedBoundaryElement = typeof boundaryElement == "function" ? boundaryElement() : boundaryElement;
142
+ if (resolvedBoundaryElement && !resolvedBoundaryElement.contains(target))
143
+ return;
144
+ const elements = (Array.isArray(elementsArg) ? [legacyElement, ...elementsArg] : elementsArg()).flat();
145
+ for (const el of elements)
146
+ if (el && (target === el || el.contains(target)))
156
147
  return;
157
- }
158
- }, [element, elementsArg]), useEffect(() => {
159
- if (!listener) return;
160
- const handleWindowMouseDown = (evt) => {
161
- const target = evt.target;
162
- if (target instanceof Node && !(boundaryElement && !boundaryElement.contains(target))) {
163
- for (const el of elements)
164
- if (target === el || el.contains(target))
165
- return;
166
- listener(evt);
167
- }
168
- };
169
- return window.addEventListener("mousedown", handleWindowMouseDown), () => {
170
- window.removeEventListener("mousedown", handleWindowMouseDown);
148
+ listener(evt);
149
+ }), hasListener = !!listener;
150
+ if (useEffect(() => {
151
+ if (!hasListener) return;
152
+ const handleEvent = (evt) => onEvent(evt);
153
+ return document.addEventListener("mousedown", handleEvent), () => {
154
+ document.removeEventListener("mousedown", handleEvent);
171
155
  };
172
- }, [boundaryElement, listener, elements]), setElement;
156
+ }, [hasListener, onEvent]), Array.isArray(elementsArg))
157
+ return setLegacyElement;
173
158
  }
174
159
  function useCustomValidity(ref, customValidity) {
175
160
  useEffect(() => {
@@ -520,21 +505,13 @@ function useGlobalKeyDown(onKeyDown) {
520
505
  function useMatchMedia(mediaQueryString, getServerSnapshot2) {
521
506
  const { subscribe: subscribe2, getSnapshot } = useMemo(() => {
522
507
  let MEDIA_QUERY_CACHE;
523
- function getMatchMedia() {
524
- return MEDIA_QUERY_CACHE === void 0 && (MEDIA_QUERY_CACHE = window.matchMedia(mediaQueryString)), MEDIA_QUERY_CACHE;
525
- }
508
+ const getMatchMedia = () => (MEDIA_QUERY_CACHE || (MEDIA_QUERY_CACHE = window.matchMedia(mediaQueryString)), MEDIA_QUERY_CACHE);
526
509
  return {
527
510
  subscribe: (onStoreChange) => {
528
511
  const matchMedia = getMatchMedia();
529
512
  return matchMedia.addEventListener("change", onStoreChange), () => matchMedia.removeEventListener("change", onStoreChange);
530
513
  },
531
- getSnapshot: () => {
532
- try {
533
- return getMatchMedia().matches;
534
- } catch (err) {
535
- throw new Error(`Failed to match media query: ${mediaQueryString}`, { cause: err });
536
- }
537
- }
514
+ getSnapshot: () => getMatchMedia().matches
538
515
  };
539
516
  }, [mediaQueryString]);
540
517
  return useDebugValue(mediaQueryString), useSyncExternalStore(subscribe2, getSnapshot, getServerSnapshot2);
@@ -5132,14 +5109,11 @@ const Root$7 = styled(Layer)(responsivePaddingStyle, dialogStyle, responsiveDial
5132
5109
  [boundaryElement, isTopLayer, onClose, portalElement]
5133
5110
  )
5134
5111
  ), useClickOutside(
5135
- useCallback(
5136
- (event) => {
5137
- if (!isTopLayer || !onClickOutside) return;
5138
- const target = event.target;
5139
- target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5140
- },
5141
- [boundaryElement, isTopLayer, onClickOutside, portalElement]
5142
- ),
5112
+ (event) => {
5113
+ if (!isTopLayer || !onClickOutside) return;
5114
+ const target = event.target;
5115
+ target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5116
+ },
5143
5117
  [rootElement]
5144
5118
  );
5145
5119
  const setRef = useCallback((el) => {
@@ -5476,13 +5450,7 @@ const Root$5 = styled(Box)`
5476
5450
  );
5477
5451
  useEffect(() => {
5478
5452
  onItemSelect && onItemSelect(activeIndex);
5479
- }, [activeIndex, onItemSelect]), useClickOutside(
5480
- useCallback(
5481
- (event) => isTopLayer && onClickOutside && onClickOutside(event),
5482
- [isTopLayer, onClickOutside]
5483
- ),
5484
- [rootElement]
5485
- ), useGlobalKeyDown(
5453
+ }, [activeIndex, onItemSelect]), useClickOutside((event) => isTopLayer && onClickOutside && onClickOutside(event), [rootElement]), useGlobalKeyDown(
5486
5454
  useCallback(
5487
5455
  (event) => {
5488
5456
  isTopLayer && event.key === "Escape" && (event.stopPropagation(), onEscape && onEscape());