@sanity/ui 2.7.0 → 2.7.1-canary.1

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
@@ -628,7 +628,7 @@ export declare interface CheckboxProps {
628
628
  /**
629
629
  * @public
630
630
  */
631
- export declare type ClickOutsideListener = (event: MouseEvent) => void
631
+ export declare type ClickOutsideListener = (event: MouseEvent | TouchEvent) => void
632
632
 
633
633
  /**
634
634
  * @public
@@ -1432,7 +1432,7 @@ export declare interface MenuProps extends ResponsivePaddingProps {
1432
1432
  * @deprecated Use `shouldFocus="last"` instead.
1433
1433
  */
1434
1434
  focusLast?: boolean
1435
- onClickOutside?: (event: MouseEvent) => void
1435
+ onClickOutside?: (event: MouseEvent | TouchEvent) => void
1436
1436
  onEscape?: () => void
1437
1437
  onItemClick?: () => void
1438
1438
  onItemSelect?: (index: number) => void
@@ -2653,9 +2653,48 @@ export declare function useBoundaryElement(): BoundaryElementContextValue
2653
2653
  */
2654
2654
  export declare function useClickOutside(
2655
2655
  listener: ClickOutsideListener,
2656
- elementsArg?: Array<HTMLElement | HTMLElement[] | null>,
2656
+ elementsArg: () => (HTMLElement | HTMLElement[] | null)[],
2657
2657
  boundaryElement?: HTMLElement | null,
2658
- ): (el: HTMLElement | null) => void
2658
+ ): void
2659
+
2660
+ /**
2661
+ * @public
2662
+ * @deprecated
2663
+ * Instead of:
2664
+ * ```tsx
2665
+ * const buttonRef = useRef(null)
2666
+ * const setElement = useClickOutside(() => {}, [buttonRef.current])
2667
+ * return (
2668
+ * <>
2669
+ * <button ref={buttonRef} />
2670
+ * {open && <div ref={setElement} />}
2671
+ * </>
2672
+ * )
2673
+ * ```
2674
+ * Use:
2675
+ * ```tsx
2676
+ * const buttonRef = useRef()
2677
+ * const [element, setElement] = useState(null)
2678
+ * useClickOutside(() => {}, () => [buttonRef.current, element])
2679
+ * return (
2680
+ * <>
2681
+ * <button ref={buttonRef} />
2682
+ * {open && <div ref={setElement} />}
2683
+ * </>
2684
+ * )
2685
+ * ```
2686
+ */
2687
+ export declare function useClickOutside(
2688
+ listener: ClickOutsideListener,
2689
+ elementsArg: (HTMLElement | HTMLElement[] | null)[],
2690
+ boundaryElement?: HTMLElement | null,
2691
+ ): UseClickOutsideSetElement
2692
+
2693
+ /**
2694
+ * @public
2695
+ * @deprecated -- do not use
2696
+ */
2697
+ export declare type UseClickOutsideSetElement = (el: HTMLElement | null) => void
2659
2698
 
2660
2699
  /**
2661
2700
  * @beta
package/dist/index.d.ts CHANGED
@@ -628,7 +628,7 @@ export declare interface CheckboxProps {
628
628
  /**
629
629
  * @public
630
630
  */
631
- export declare type ClickOutsideListener = (event: MouseEvent) => void
631
+ export declare type ClickOutsideListener = (event: MouseEvent | TouchEvent) => void
632
632
 
633
633
  /**
634
634
  * @public
@@ -1432,7 +1432,7 @@ export declare interface MenuProps extends ResponsivePaddingProps {
1432
1432
  * @deprecated Use `shouldFocus="last"` instead.
1433
1433
  */
1434
1434
  focusLast?: boolean
1435
- onClickOutside?: (event: MouseEvent) => void
1435
+ onClickOutside?: (event: MouseEvent | TouchEvent) => void
1436
1436
  onEscape?: () => void
1437
1437
  onItemClick?: () => void
1438
1438
  onItemSelect?: (index: number) => void
@@ -2653,9 +2653,48 @@ export declare function useBoundaryElement(): BoundaryElementContextValue
2653
2653
  */
2654
2654
  export declare function useClickOutside(
2655
2655
  listener: ClickOutsideListener,
2656
- elementsArg?: Array<HTMLElement | HTMLElement[] | null>,
2656
+ elementsArg: () => (HTMLElement | HTMLElement[] | null)[],
2657
2657
  boundaryElement?: HTMLElement | null,
2658
- ): (el: HTMLElement | null) => void
2658
+ ): void
2659
+
2660
+ /**
2661
+ * @public
2662
+ * @deprecated
2663
+ * Instead of:
2664
+ * ```tsx
2665
+ * const buttonRef = useRef(null)
2666
+ * const setElement = useClickOutside(() => {}, [buttonRef.current])
2667
+ * return (
2668
+ * <>
2669
+ * <button ref={buttonRef} />
2670
+ * {open && <div ref={setElement} />}
2671
+ * </>
2672
+ * )
2673
+ * ```
2674
+ * Use:
2675
+ * ```tsx
2676
+ * const buttonRef = useRef()
2677
+ * const [element, setElement] = useState(null)
2678
+ * useClickOutside(() => {}, () => [buttonRef.current, element])
2679
+ * return (
2680
+ * <>
2681
+ * <button ref={buttonRef} />
2682
+ * {open && <div ref={setElement} />}
2683
+ * </>
2684
+ * )
2685
+ * ```
2686
+ */
2687
+ export declare function useClickOutside(
2688
+ listener: ClickOutsideListener,
2689
+ elementsArg: (HTMLElement | HTMLElement[] | null)[],
2690
+ boundaryElement?: HTMLElement | null,
2691
+ ): UseClickOutsideSetElement
2692
+
2693
+ /**
2694
+ * @public
2695
+ * @deprecated -- do not use
2696
+ */
2697
+ export declare type UseClickOutsideSetElement = (el: HTMLElement | null) => void
2659
2698
 
2660
2699
  /**
2661
2700
  * @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,25 @@ 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
+ const target = evt.target;
137
+ if (!(target instanceof Node) || boundaryElement && !boundaryElement.contains(target))
146
138
  return;
147
- }
148
- for (const el of prevElements)
149
- if (!nextElements.includes(el)) {
150
- setElements(nextElements), elementsRef.current = nextElements;
139
+ const elements = (Array.isArray(elementsArg) ? [legacyElement, ...elementsArg] : elementsArg()).flat();
140
+ for (const el of elements)
141
+ if (el && (target === el || el.contains(target)))
151
142
  return;
152
- }
153
- for (const el of nextElements)
154
- if (!prevElements.includes(el)) {
155
- setElements(nextElements), elementsRef.current = nextElements;
156
- 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);
143
+ listener(evt);
144
+ }), hasListener = !!listener;
145
+ if (useEffect(() => {
146
+ if (!hasListener) return;
147
+ const handleEvent = (evt) => onEvent(evt);
148
+ return document.addEventListener("mousedown", handleEvent), document.addEventListener("touchstart", handleEvent), () => {
149
+ document.removeEventListener("mousedown", handleEvent), document.removeEventListener("touchstart", handleEvent);
171
150
  };
172
- }, [boundaryElement, listener, elements]), setElement;
151
+ }, [hasListener, onEvent]), Array.isArray(elementsArg))
152
+ return setLegacyElement;
173
153
  }
174
154
  function useCustomValidity(ref, customValidity) {
175
155
  useEffect(() => {