@sanity/ui 2.6.4-canary.1 → 2.6.4-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.
Files changed (37) hide show
  1. package/dist/index.d.mts +42 -6
  2. package/dist/index.d.ts +42 -6
  3. package/dist/index.esm.js +90 -156
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +88 -154
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +90 -156
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +1 -1
  10. package/src/core/components/breadcrumbs/breadcrumbs.tsx +15 -6
  11. package/src/core/components/dialog/dialog.tsx +12 -21
  12. package/src/core/components/menu/menu.tsx +11 -18
  13. package/src/core/components/menu/menuButton.tsx +1 -1
  14. package/src/core/components/menu/menuContext.ts +1 -1
  15. package/src/core/components/menu/useMenuController.ts +11 -17
  16. package/src/core/components/toast/styles.ts +2 -1
  17. package/src/core/components/toast/useToast.ts +1 -0
  18. package/src/core/components/tree/tree.tsx +1 -0
  19. package/src/core/components/tree/treeItem.tsx +1 -0
  20. package/src/core/helpers/focus.ts +1 -0
  21. package/src/core/helpers/scroll.ts +1 -0
  22. package/src/core/hooks/index.ts +3 -2
  23. package/src/core/hooks/useClickOutside.ts +38 -72
  24. package/src/core/hooks/useElementSize.ts +1 -0
  25. package/src/core/hooks/useMatchMedia.ts +46 -0
  26. package/src/core/hooks/useMediaIndex/useMediaIndex.ts +2 -10
  27. package/src/core/hooks/usePrefersDark.ts +10 -55
  28. package/src/core/hooks/usePrefersReducedMotion.ts +10 -56
  29. package/src/core/primitives/popover/__workshop__/AlignedStory.tsx +9 -7
  30. package/src/core/primitives/tooltip/__workshop__/customPortal.tsx +8 -6
  31. package/src/core/primitives/tooltip/tooltip.tsx +25 -21
  32. package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupProvider.tsx +1 -0
  33. package/src/core/utils/layer/layerProvider.tsx +1 -0
  34. package/src/core/utils/portal/__workshop__/named.tsx +10 -8
  35. package/src/core/utils/portal/portalProvider.tsx +2 -3
  36. package/src/core/hooks/_internal/index.ts +0 -1
  37. package/src/core/hooks/_internal/useUnique.ts +0 -34
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
@@ -2649,13 +2649,22 @@ export declare function useArrayProp<T extends ArrayPropPrimitive = ArrayPropPri
2649
2649
  export declare function useBoundaryElement(): BoundaryElementContextValue
2650
2650
 
2651
2651
  /**
2652
+ * Use the callback version of `elementsArg` if you're using `useRef` to handle elements:
2653
+ * ```tsx
2654
+ * useClickOutside(
2655
+ * () => {},
2656
+ * () => [ref.current],
2657
+ * )
2658
+ *
2652
2659
  * @public
2653
2660
  */
2654
2661
  export declare function useClickOutside(
2655
2662
  listener: ClickOutsideListener,
2656
- elementsArg?: Array<HTMLElement | HTMLElement[] | null>,
2663
+ elementsArg?:
2664
+ | Array<HTMLElement | HTMLElement[] | null>
2665
+ | (() => Array<HTMLElement | HTMLElement[] | null>),
2657
2666
  boundaryElement?: HTMLElement | null,
2658
- ): (el: HTMLElement | null) => void
2667
+ ): void
2659
2668
 
2660
2669
  /**
2661
2670
  * @beta
@@ -2713,6 +2722,18 @@ export declare function useGlobalKeyDown(onKeyDown: (event: KeyboardEvent) => vo
2713
2722
  */
2714
2723
  export declare function useLayer(): LayerContextValue
2715
2724
 
2725
+ /**
2726
+ * Efficiently subscribes to `window.matchMedia` queries
2727
+ *
2728
+ * @param getServerSnapshot - Only called during server-side rendering, and hydration if using hydrateRoot. Required if the hook is called during SSR (https://react.dev/reference/react/useSyncExternalStore#adding-support-for-server-rendering)
2729
+ *
2730
+ * @public
2731
+ */
2732
+ export declare function useMatchMedia(
2733
+ mediaQueryString: `(${string})`,
2734
+ getServerSnapshot?: () => boolean,
2735
+ ): boolean
2736
+
2716
2737
  /**
2717
2738
  * This API might change. DO NOT USE IN PRODUCTION.
2718
2739
  * @beta
@@ -2725,15 +2746,30 @@ export declare function useMediaIndex(): number
2725
2746
  export declare function usePortal(): PortalContextValue
2726
2747
 
2727
2748
  /**
2749
+ * Returns true if a dark color scheme is preferred, false if a light color scheme is preferred or the preference is not known.
2750
+ *
2751
+ * @param getServerSnapshot - Only called during server-side rendering, and hydration if using hydrateRoot. Since the server environment doesn't have access to the DOM, we can't determine the current value of the media query and we assume `(prefers-color-scheme: light)` since it's the most common scheme (https://react.dev/reference/react/useSyncExternalStore#adding-support-for-server-rendering)
2752
+ *
2753
+ * If you persist the detected preference in a cookie or a header then you may implement your own server snapshot to read it.
2754
+ * Chrome supports reading the `prefers-color-scheme` media query from a header if the server response: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-Prefers-Color-Scheme
2755
+ * @example https://gist.github.com/stipsan/13c0cccf8dfc34f4b44bb1b984baf7df
2756
+ *
2728
2757
  * @public
2729
2758
  */
2730
- export declare function usePrefersDark(): boolean
2759
+ export declare function usePrefersDark(getServerSnapshot?: () => boolean): boolean
2731
2760
 
2732
2761
  /**
2733
2762
  * Returns true if motion should be reduced
2763
+ *
2764
+ * @param getServerSnapshot - Only called during server-side rendering, and hydration if using hydrateRoot. Since the server environment doesn't have access to the DOM, we can't determine the current value of the media query and we assume `(prefers-reduced-motion: no-preference)` since it's the most common scheme (https://react.dev/reference/react/useSyncExternalStore#adding-support-for-server-rendering)
2765
+ *
2766
+ * If you persist the detected preference in a cookie or a header then you may implement your own server snapshot to read it.
2767
+ * Chrome supports reading the `prefers-reduced-motion` media query from a header if the server response: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-Prefers-Reduced-Motion
2768
+ * @example https://gist.github.com/stipsan/0c0f839a27842249cada893e9fb7767b
2769
+ *
2734
2770
  * @public
2735
2771
  */
2736
- export declare function usePrefersReducedMotion(): boolean
2772
+ export declare function usePrefersReducedMotion(getServerSnapshot?: () => boolean): boolean
2737
2773
 
2738
2774
  /**
2739
2775
  * @public
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
@@ -2649,13 +2649,22 @@ export declare function useArrayProp<T extends ArrayPropPrimitive = ArrayPropPri
2649
2649
  export declare function useBoundaryElement(): BoundaryElementContextValue
2650
2650
 
2651
2651
  /**
2652
+ * Use the callback version of `elementsArg` if you're using `useRef` to handle elements:
2653
+ * ```tsx
2654
+ * useClickOutside(
2655
+ * () => {},
2656
+ * () => [ref.current],
2657
+ * )
2658
+ *
2652
2659
  * @public
2653
2660
  */
2654
2661
  export declare function useClickOutside(
2655
2662
  listener: ClickOutsideListener,
2656
- elementsArg?: Array<HTMLElement | HTMLElement[] | null>,
2663
+ elementsArg?:
2664
+ | Array<HTMLElement | HTMLElement[] | null>
2665
+ | (() => Array<HTMLElement | HTMLElement[] | null>),
2657
2666
  boundaryElement?: HTMLElement | null,
2658
- ): (el: HTMLElement | null) => void
2667
+ ): void
2659
2668
 
2660
2669
  /**
2661
2670
  * @beta
@@ -2713,6 +2722,18 @@ export declare function useGlobalKeyDown(onKeyDown: (event: KeyboardEvent) => vo
2713
2722
  */
2714
2723
  export declare function useLayer(): LayerContextValue
2715
2724
 
2725
+ /**
2726
+ * Efficiently subscribes to `window.matchMedia` queries
2727
+ *
2728
+ * @param getServerSnapshot - Only called during server-side rendering, and hydration if using hydrateRoot. Required if the hook is called during SSR (https://react.dev/reference/react/useSyncExternalStore#adding-support-for-server-rendering)
2729
+ *
2730
+ * @public
2731
+ */
2732
+ export declare function useMatchMedia(
2733
+ mediaQueryString: `(${string})`,
2734
+ getServerSnapshot?: () => boolean,
2735
+ ): boolean
2736
+
2716
2737
  /**
2717
2738
  * This API might change. DO NOT USE IN PRODUCTION.
2718
2739
  * @beta
@@ -2725,15 +2746,30 @@ export declare function useMediaIndex(): number
2725
2746
  export declare function usePortal(): PortalContextValue
2726
2747
 
2727
2748
  /**
2749
+ * Returns true if a dark color scheme is preferred, false if a light color scheme is preferred or the preference is not known.
2750
+ *
2751
+ * @param getServerSnapshot - Only called during server-side rendering, and hydration if using hydrateRoot. Since the server environment doesn't have access to the DOM, we can't determine the current value of the media query and we assume `(prefers-color-scheme: light)` since it's the most common scheme (https://react.dev/reference/react/useSyncExternalStore#adding-support-for-server-rendering)
2752
+ *
2753
+ * If you persist the detected preference in a cookie or a header then you may implement your own server snapshot to read it.
2754
+ * Chrome supports reading the `prefers-color-scheme` media query from a header if the server response: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-Prefers-Color-Scheme
2755
+ * @example https://gist.github.com/stipsan/13c0cccf8dfc34f4b44bb1b984baf7df
2756
+ *
2728
2757
  * @public
2729
2758
  */
2730
- export declare function usePrefersDark(): boolean
2759
+ export declare function usePrefersDark(getServerSnapshot?: () => boolean): boolean
2731
2760
 
2732
2761
  /**
2733
2762
  * Returns true if motion should be reduced
2763
+ *
2764
+ * @param getServerSnapshot - Only called during server-side rendering, and hydration if using hydrateRoot. Since the server environment doesn't have access to the DOM, we can't determine the current value of the media query and we assume `(prefers-reduced-motion: no-preference)` since it's the most common scheme (https://react.dev/reference/react/useSyncExternalStore#adding-support-for-server-rendering)
2765
+ *
2766
+ * If you persist the detected preference in a cookie or a header then you may implement your own server snapshot to read it.
2767
+ * Chrome supports reading the `prefers-reduced-motion` media query from a header if the server response: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-Prefers-Reduced-Motion
2768
+ * @example https://gist.github.com/stipsan/0c0f839a27842249cada893e9fb7767b
2769
+ *
2734
2770
  * @public
2735
2771
  */
2736
- export declare function usePrefersReducedMotion(): boolean
2772
+ export declare function usePrefersReducedMotion(getServerSnapshot?: () => boolean): boolean
2737
2773
 
2738
2774
  /**
2739
2775
  * @public
package/dist/index.esm.js CHANGED
@@ -1,11 +1,11 @@
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, createContext, useContext, useSyncExternalStore, useImperativeHandle, forwardRef, useId, useCallback, Children, isValidElement, cloneElement, Component, memo, useReducer, Fragment as Fragment$1, startTransition } from "react";
3
+ import { useMemo, useEffect, useState, useRef, useImperativeHandle, useDebugValue, useSyncExternalStore, createContext, useContext, forwardRef, useId, useCallback, Children, isValidElement, cloneElement, Component, memo, 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";
7
7
  import Refractor from "react-refractor";
8
- import { detectOverflow, flip, offset, shift, arrow, hide, useFloating, autoUpdate } from "@floating-ui/react-dom";
8
+ import { detectOverflow, flip, offset, shift, arrow, hide, useFloating, autoUpdate, size as size$2 } from "@floating-ui/react-dom";
9
9
  import { motion, AnimatePresence } from "framer-motion";
10
10
  import { createPortal } from "react-dom";
11
11
  import { useEffectEvent } from "use-effect-event";
@@ -131,45 +131,26 @@ 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 eventHandler = 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;
151
- return;
152
- }
153
- for (const el of nextElements)
154
- if (!prevElements.includes(el)) {
155
- setElements(nextElements), elementsRef.current = nextElements;
139
+ const elements = (Array.isArray(elementsArg) ? elementsArg : elementsArg()).flat();
140
+ for (const el of elements)
141
+ if (el && (target === el || el.contains(target)))
156
142
  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);
171
- };
172
- }, [boundaryElement, listener, elements]), setElement;
143
+ listener(evt);
144
+ });
145
+ useEffect(() => (document.addEventListener("mousedown", eventHandler), document.addEventListener("touchstart", eventHandler), () => {
146
+ document.removeEventListener("mousedown", eventHandler), document.removeEventListener("touchstart", eventHandler);
147
+ }), [eventHandler]);
148
+ }
149
+ function useCustomValidity(ref, customValidity) {
150
+ useEffect(() => {
151
+ var _a;
152
+ (_a = ref.current) == null || _a.setCustomValidity(customValidity || "");
153
+ }, [customValidity, ref]);
173
154
  }
174
155
  var resizeObservers = [], hasActiveObservations = function() {
175
156
  return resizeObservers.some(function(ro) {
@@ -504,9 +485,27 @@ function useElementRect(element) {
504
485
  const elementSize = useElementSize(element);
505
486
  return (elementSize == null ? void 0 : elementSize._contentRect) || null;
506
487
  }
488
+ function useForwardedRef(ref) {
489
+ const innerRef = useRef(null);
490
+ return useImperativeHandle(ref, () => innerRef.current), innerRef;
491
+ }
507
492
  function useGlobalKeyDown(onKeyDown) {
508
493
  return useEffect(() => (addEventListener("keydown", onKeyDown), () => removeEventListener("keydown", onKeyDown)), [onKeyDown]);
509
494
  }
495
+ function useMatchMedia(mediaQueryString, getServerSnapshot2) {
496
+ const { subscribe: subscribe2, getSnapshot } = useMemo(() => {
497
+ let MEDIA_QUERY_CACHE;
498
+ const getMatchMedia = () => (MEDIA_QUERY_CACHE || (MEDIA_QUERY_CACHE = window.matchMedia(mediaQueryString)), MEDIA_QUERY_CACHE);
499
+ return {
500
+ subscribe: (onStoreChange) => {
501
+ const matchMedia = getMatchMedia();
502
+ return matchMedia.addEventListener("change", onStoreChange), () => matchMedia.removeEventListener("change", onStoreChange);
503
+ },
504
+ getSnapshot: () => getMatchMedia().matches
505
+ };
506
+ }, [mediaQueryString]);
507
+ return useDebugValue(mediaQueryString), useSyncExternalStore(subscribe2, getSnapshot, getServerSnapshot2);
508
+ }
510
509
  function getGlobalScope() {
511
510
  if (typeof globalThis < "u") return globalThis;
512
511
  if (typeof window < "u") return window;
@@ -549,7 +548,6 @@ function useTheme() {
549
548
  function useTheme_v2() {
550
549
  return getTheme_v2(useTheme$1());
551
550
  }
552
- const MEDIA_STORE_CACHE = /* @__PURE__ */ new WeakMap();
553
551
  function _getMediaQuery(media, index) {
554
552
  return index === 0 ? `screen and (max-width: ${media[index] - 1}px)` : index === media.length ? `screen and (min-width: ${media[index - 1]}px)` : `screen and (min-width: ${media[index - 1]}px) and (max-width: ${media[index] - 1}px)`;
555
553
  }
@@ -584,57 +582,18 @@ function _createMediaStore(media) {
584
582
  };
585
583
  } };
586
584
  }
587
- function getServerSnapshot$2() {
585
+ function getServerSnapshot() {
588
586
  return 0;
589
587
  }
590
588
  function useMediaIndex() {
591
- const { media } = useTheme_v2();
592
- let store = MEDIA_STORE_CACHE.get(media);
593
- return store || (store = _createMediaStore(media), MEDIA_STORE_CACHE.set(media, store)), useSyncExternalStore(store.subscribe, store.getSnapshot, getServerSnapshot$2);
594
- }
595
- let MEDIA_QUERY_CACHE$1;
596
- function getMatchMedia$1() {
597
- return MEDIA_QUERY_CACHE$1 || (MEDIA_QUERY_CACHE$1 = window.matchMedia("(prefers-color-scheme: dark)")), MEDIA_QUERY_CACHE$1;
589
+ const { media } = useTheme_v2(), store = useMemo(() => _createMediaStore(media), [media]);
590
+ return useSyncExternalStore(store.subscribe, store.getSnapshot, getServerSnapshot);
598
591
  }
599
- function subscribe$2(onStoreChange) {
600
- const matchMedia = getMatchMedia$1();
601
- return matchMedia.addEventListener("change", onStoreChange), () => matchMedia.removeEventListener("change", onStoreChange);
592
+ function usePrefersDark(getServerSnapshot2 = () => !1) {
593
+ return useMatchMedia("(prefers-color-scheme: dark)", getServerSnapshot2);
602
594
  }
603
- function getSnapshot$1() {
604
- return getMatchMedia$1().matches;
605
- }
606
- function getServerSnapshot$1() {
607
- return !1;
608
- }
609
- function usePrefersDark() {
610
- return useSyncExternalStore(subscribe$2, getSnapshot$1, getServerSnapshot$1);
611
- }
612
- let MEDIA_QUERY_CACHE;
613
- function getMatchMedia() {
614
- return MEDIA_QUERY_CACHE || (MEDIA_QUERY_CACHE = window.matchMedia("(prefers-reduced-motion: reduce)")), MEDIA_QUERY_CACHE;
615
- }
616
- function subscribe$1(onStoreChange) {
617
- const matchMedia = getMatchMedia();
618
- return matchMedia.addEventListener("change", onStoreChange), () => matchMedia.removeEventListener("change", onStoreChange);
619
- }
620
- function getSnapshot() {
621
- return getMatchMedia().matches;
622
- }
623
- function getServerSnapshot() {
624
- return !1;
625
- }
626
- function usePrefersReducedMotion() {
627
- return useSyncExternalStore(subscribe$1, getSnapshot, getServerSnapshot);
628
- }
629
- function useForwardedRef(ref) {
630
- const innerRef = useRef(null);
631
- return useImperativeHandle(ref, () => innerRef.current), innerRef;
632
- }
633
- function useCustomValidity(ref, customValidity) {
634
- useEffect(() => {
635
- var _a;
636
- (_a = ref.current) == null || _a.setCustomValidity(customValidity || "");
637
- }, [customValidity, ref]);
595
+ function usePrefersReducedMotion(getServerSnapshot2 = () => !1) {
596
+ return useMatchMedia("(prefers-reduced-motion: reduce)", getServerSnapshot2);
638
597
  }
639
598
  function responsiveBorderStyle() {
640
599
  return [border, borderTop, borderRight, borderBottom, borderLeft];
@@ -3060,16 +3019,6 @@ function Portal(props) {
3060
3019
  const { children, __unstable_name: name } = props, portal = usePortal(), portalElement = (name ? portal.elements && portal.elements[name] : portal.element) || ((_a = portal.elements) == null ? void 0 : _a.default);
3061
3020
  return portalElement ? createPortal(children, portalElement) : null;
3062
3021
  }
3063
- function useUnique(value) {
3064
- const valueRef = useRef(value);
3065
- return _isEqual(valueRef.current, value) || (valueRef.current = value), valueRef.current;
3066
- }
3067
- function _isEqual(objA, objB) {
3068
- if (!objA || !objB)
3069
- return objA === objB;
3070
- const keysA = Object.keys(objA), keysB = Object.keys(objB);
3071
- return keysA.length !== keysB.length ? !1 : keysA.every((key2) => objA[key2] === objB[key2]);
3072
- }
3073
3022
  function useMounted() {
3074
3023
  return useSyncExternalStore(
3075
3024
  subscribe,
@@ -3080,7 +3029,7 @@ function useMounted() {
3080
3029
  const subscribe = () => () => {
3081
3030
  };
3082
3031
  function PortalProvider(props) {
3083
- const { boundaryElement, children, element, __unstable_elements: elementsProp } = props, elements = useUnique(elementsProp), mounted = useMounted(), value = useMemo(() => ({
3032
+ const { boundaryElement, children, element, __unstable_elements: elements } = props, mounted = useMounted(), value = useMemo(() => ({
3084
3033
  version: 0,
3085
3034
  boundaryElement: boundaryElement || null,
3086
3035
  element: element || mounted ? document.body : null,
@@ -4343,7 +4292,6 @@ function TooltipDelayGroupProvider(props) {
4343
4292
  }
4344
4293
  const Root$a = styled(Layer)`
4345
4294
  pointer-events: none;
4346
- max-width: ${({ $maxWidth }) => $maxWidth}px;
4347
4295
  `, Tooltip = forwardRef(function(props, forwardedRef) {
4348
4296
  var _a, _b, _c, _d, _e, _f, _g;
4349
4297
  const boundaryElementContext = useBoundaryElement(), { layer } = useTheme_v2(), {
@@ -4365,18 +4313,21 @@ const Root$a = styled(Layer)`
4365
4313
  ...restProps
4366
4314
  } = props, animate = usePrefersReducedMotion() ? !1 : _animate, fallbackPlacements = useArrayProp(fallbackPlacementsProp), ref = useRef(null), [referenceElement, setReferenceElement] = useState(null), arrowRef = useRef(null), rootBoundary = "viewport";
4367
4315
  useImperativeHandle(forwardedRef, () => ref.current);
4368
- const portal = usePortal(), portalElement = typeof portalProp == "string" ? ((_c = portal.elements) == null ? void 0 : _c[portalProp]) || null : portal.element, mounted = useMounted(), tooltipWidth = useMemo(() => {
4369
- const availableWidths = [
4370
- ...boundaryElement ? [boundaryElement.offsetWidth] : [],
4371
- portalElement != null && portalElement.offsetWidth || mounted ? document.body.offsetWidth : (
4372
- // We don't actually know what the width of the body is during SSR, so we'll just assume it's 800px or larger
4373
- 800
4374
- )
4375
- ];
4376
- return Math.min(...availableWidths) - DEFAULT_TOOLTIP_PADDING * 2;
4377
- }, [boundaryElement, mounted, portalElement]), middleware = useMemo(() => {
4316
+ const portal = usePortal(), portalElement = typeof portalProp == "string" ? ((_c = portal.elements) == null ? void 0 : _c[portalProp]) || null : portal.element, middleware = useMemo(() => {
4378
4317
  const ret = [];
4379
4318
  return ret.push(
4319
+ size$2({
4320
+ apply({ elements }) {
4321
+ const availableWidths = [
4322
+ ...boundaryElement ? [boundaryElement.offsetWidth] : [],
4323
+ (portalElement == null ? void 0 : portalElement.offsetWidth) || document.body.offsetWidth
4324
+ ], tooltipWidth = Math.min(...availableWidths) - DEFAULT_TOOLTIP_PADDING * 2;
4325
+ Object.assign(elements.floating.style, {
4326
+ maxWidth: tooltipWidth > 0 ? `${tooltipWidth}px` : void 0
4327
+ });
4328
+ }
4329
+ })
4330
+ ), ret.push(
4380
4331
  flip({
4381
4332
  boundary: boundaryElement || void 0,
4382
4333
  fallbackPlacements,
@@ -4390,7 +4341,7 @@ const Root$a = styled(Layer)`
4390
4341
  padding: DEFAULT_TOOLTIP_PADDING
4391
4342
  })
4392
4343
  ), arrowProp && ret.push(arrow({ element: arrowRef, padding: DEFAULT_TOOLTIP_PADDING })), animate && ret.push(origin), ret;
4393
- }, [animate, arrowProp, boundaryElement, fallbackPlacements]), { floatingStyles, placement, middlewareData, refs, update } = useFloating({
4344
+ }, [animate, arrowProp, boundaryElement, fallbackPlacements, portalElement]), { floatingStyles, placement, middlewareData, refs, update } = useFloating({
4394
4345
  middleware,
4395
4346
  placement: placementProp,
4396
4347
  whileElementsMounted: autoUpdate
@@ -4500,7 +4451,6 @@ const Root$a = styled(Layer)`
4500
4451
  ref: setFloating,
4501
4452
  style: floatingStyles,
4502
4453
  zOffset,
4503
- $maxWidth: tooltipWidth,
4504
4454
  children: /* @__PURE__ */ jsx(
4505
4455
  TooltipCard,
4506
4456
  {
@@ -4966,8 +4916,8 @@ const AUTOCOMPLETE_LISTBOX_IGNORE_KEYS = [
4966
4916
  appearance: none;
4967
4917
  margin: -4px;
4968
4918
  `, Breadcrumbs = forwardRef(function(props, ref) {
4969
- const { children, maxLength, separator, space: spaceRaw = 2, ...restProps } = props, space = useArrayProp(spaceRaw), [open, setOpen] = useState(!1), [expandElement, setExpandElement] = useState(null), [popoverElement, setPopoverElement] = useState(null), collapse = useCallback(() => setOpen(!1), []), expand = useCallback(() => setOpen(!0), []);
4970
- useClickOutside(collapse, [expandElement, popoverElement]);
4919
+ const { children, maxLength, separator, space: spaceRaw = 2, ...restProps } = props, space = useArrayProp(spaceRaw), [open, setOpen] = useState(!1), expandElementRef = useRef(null), popoverElementRef = useRef(null), collapse = useCallback(() => setOpen(!1), []), expand = useCallback(() => setOpen(!0), []);
4920
+ useClickOutside(collapse, () => [expandElementRef.current, popoverElementRef.current]);
4971
4921
  const rawItems = useMemo(() => Children.toArray(children).filter(isValidElement), [children]), items = useMemo(() => {
4972
4922
  const len = rawItems.length;
4973
4923
  if (maxLength && len > maxLength) {
@@ -4982,7 +4932,7 @@ const AUTOCOMPLETE_LISTBOX_IGNORE_KEYS = [
4982
4932
  open,
4983
4933
  placement: "top",
4984
4934
  portal: !0,
4985
- ref: setPopoverElement,
4935
+ ref: popoverElementRef,
4986
4936
  children: /* @__PURE__ */ jsx(
4987
4937
  ExpandButton,
4988
4938
  {
@@ -4990,7 +4940,7 @@ const AUTOCOMPLETE_LISTBOX_IGNORE_KEYS = [
4990
4940
  mode: "bleed",
4991
4941
  onClick: open ? collapse : expand,
4992
4942
  padding: 1,
4993
- ref: setExpandElement,
4943
+ ref: expandElementRef,
4994
4944
  selected: open,
4995
4945
  text: "\u2026"
4996
4946
  }
@@ -5115,8 +5065,8 @@ const Root$7 = styled(Layer)(responsivePaddingStyle, dialogStyle, responsiveDial
5115
5065
  scheme,
5116
5066
  shadow: shadowProp,
5117
5067
  width: widthProp
5118
- } = props, portal = usePortal(), portalElement = portalProp ? ((_a = portal.elements) == null ? void 0 : _a[portalProp]) || null : portal.element, boundaryElement = useBoundaryElement().element, radius = useArrayProp(radiusProp), shadow = useArrayProp(shadowProp), width = useArrayProp(widthProp), ref = useRef(null), [rootElement, setRootElement] = useState(null), contentRef = useRef(null), layer = useLayer(), { isTopLayer } = layer, labelId = `${id}_label`, showCloseButton = !!onClose && hideCloseButton === !1, showHeader = !!header || showCloseButton;
5119
- useImperativeHandle(forwardedRef, () => ref.current), useImperativeHandle(
5068
+ } = props, portal = usePortal(), portalElement = portalProp ? ((_a = portal.elements) == null ? void 0 : _a[portalProp]) || null : portal.element, boundaryElement = useBoundaryElement().element, radius = useArrayProp(radiusProp), shadow = useArrayProp(shadowProp), width = useArrayProp(widthProp), ref = useRef(null), contentRef = useRef(null), layer = useLayer(), { isTopLayer } = layer, labelId = `${id}_label`, showCloseButton = !!onClose && hideCloseButton === !1, showHeader = !!header || showCloseButton;
5069
+ return useImperativeHandle(forwardedRef, () => ref.current), useImperativeHandle(
5120
5070
  forwardedContentRef,
5121
5071
  () => contentRef.current
5122
5072
  ), useEffect(() => {
@@ -5131,20 +5081,13 @@ const Root$7 = styled(Layer)(responsivePaddingStyle, dialogStyle, responsiveDial
5131
5081
  [boundaryElement, isTopLayer, onClose, portalElement]
5132
5082
  )
5133
5083
  ), useClickOutside(
5134
- useCallback(
5135
- (event) => {
5136
- if (!isTopLayer || !onClickOutside) return;
5137
- const target = event.target;
5138
- target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5139
- },
5140
- [boundaryElement, isTopLayer, onClickOutside, portalElement]
5141
- ),
5142
- [rootElement]
5143
- );
5144
- const setRef = useCallback((el) => {
5145
- setRootElement(el), ref.current = el;
5146
- }, []);
5147
- return /* @__PURE__ */ jsx(DialogContainer, { "data-ui": "DialogCard", width, children: /* @__PURE__ */ jsx(DialogCardRoot, { radius, ref: setRef, scheme, shadow, children: /* @__PURE__ */ jsxs(DialogLayout, { direction: "column", children: [
5084
+ (event) => {
5085
+ if (!isTopLayer || !onClickOutside) return;
5086
+ const target = event.target;
5087
+ target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5088
+ },
5089
+ () => [ref.current]
5090
+ ), /* @__PURE__ */ jsx(DialogContainer, { "data-ui": "DialogCard", width, children: /* @__PURE__ */ jsx(DialogCardRoot, { radius, ref, scheme, shadow, children: /* @__PURE__ */ jsxs(DialogLayout, { direction: "column", children: [
5148
5091
  showHeader && /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsxs(Flex, { align: "center", padding: 3, children: [
5149
5092
  /* @__PURE__ */ jsx(Box, { flex: 1, padding: 2, children: header && /* @__PURE__ */ jsx(Text, { id: labelId, size: 1, weight: "semibold", children: header }) }),
5150
5093
  showCloseButton && /* @__PURE__ */ jsx(Box, { flex: "none", children: /* @__PURE__ */ jsx(
@@ -5322,13 +5265,13 @@ function _sortElements(rootElement, elements) {
5322
5265
  elements.sort(_sort);
5323
5266
  }
5324
5267
  function useMenuController(props) {
5325
- const { onKeyDown, originElement, shouldFocus } = props, elementsRef = useRef([]), [rootElement, setRootElement] = useState(null), [activeIndex, _setActiveIndex] = useState(-1), activeIndexRef = useRef(activeIndex), activeElement = elementsRef.current[activeIndex] || null, mounted = !!rootElement, setActiveIndex = useCallback((nextActiveIndex) => {
5268
+ const { onKeyDown, originElement, shouldFocus, rootElementRef } = props, elementsRef = useRef([]), [activeIndex, _setActiveIndex] = useState(-1), activeIndexRef = useRef(activeIndex), activeElement = useMemo(() => elementsRef.current[activeIndex] || null, [activeIndex]), mounted = !!rootElementRef.current, setActiveIndex = useCallback((nextActiveIndex) => {
5326
5269
  _setActiveIndex(nextActiveIndex), activeIndexRef.current = nextActiveIndex;
5327
5270
  }, []), mount = useCallback(
5328
5271
  (element, selected) => {
5329
5272
  if (!element) return () => {
5330
5273
  };
5331
- if (elementsRef.current.indexOf(element) === -1 && (elementsRef.current.push(element), _sortElements(rootElement, elementsRef.current)), selected) {
5274
+ if (elementsRef.current.indexOf(element) === -1 && (elementsRef.current.push(element), _sortElements(rootElementRef.current, elementsRef.current)), selected) {
5332
5275
  const selectedIndex = elementsRef.current.indexOf(element);
5333
5276
  setActiveIndex(selectedIndex);
5334
5277
  }
@@ -5337,7 +5280,7 @@ function useMenuController(props) {
5337
5280
  idx > -1 && elementsRef.current.splice(idx, 1);
5338
5281
  };
5339
5282
  },
5340
- [rootElement, setActiveIndex]
5283
+ [rootElementRef, setActiveIndex]
5341
5284
  ), handleKeyDown = useCallback(
5342
5285
  (event) => {
5343
5286
  if (event.key === "Tab") {
@@ -5392,13 +5335,13 @@ function useMenuController(props) {
5392
5335
  },
5393
5336
  [setActiveIndex]
5394
5337
  ), handleItemMouseLeave = useCallback(() => {
5395
- setActiveIndex(-2), rootElement == null || rootElement.focus();
5396
- }, [setActiveIndex, rootElement]);
5338
+ var _a;
5339
+ setActiveIndex(-2), (_a = rootElementRef.current) == null || _a.focus();
5340
+ }, [rootElementRef, setActiveIndex]);
5397
5341
  return useEffect(() => {
5398
5342
  if (!mounted) return;
5399
5343
  const rafId = window.requestAnimationFrame(() => {
5400
- const _activeIndex = activeIndexRef.current;
5401
- if (_activeIndex === -1) {
5344
+ if (activeIndex === -1) {
5402
5345
  if (shouldFocus === "first") {
5403
5346
  const el = _getFocusableElements(elementsRef.current)[0];
5404
5347
  if (el) {
@@ -5415,7 +5358,7 @@ function useMenuController(props) {
5415
5358
  }
5416
5359
  return;
5417
5360
  }
5418
- const element = elementsRef.current[_activeIndex] || null;
5361
+ const element = elementsRef.current[activeIndex] || null;
5419
5362
  element == null || element.focus();
5420
5363
  });
5421
5364
  return () => {
@@ -5427,9 +5370,7 @@ function useMenuController(props) {
5427
5370
  handleItemMouseEnter,
5428
5371
  handleItemMouseLeave,
5429
5372
  handleKeyDown,
5430
- mount,
5431
- rootElement,
5432
- setRootElement
5373
+ mount
5433
5374
  };
5434
5375
  }
5435
5376
  const Root$5 = styled(Box)`
@@ -5461,23 +5402,18 @@ const Root$5 = styled(Box)`
5461
5402
  handleItemMouseEnter,
5462
5403
  handleItemMouseLeave,
5463
5404
  handleKeyDown,
5464
- mount,
5465
- rootElement,
5466
- setRootElement
5467
- } = useMenuController({ onKeyDown, originElement, shouldFocus }), handleRefChange = useCallback(
5405
+ mount
5406
+ } = useMenuController({ onKeyDown, originElement, shouldFocus, rootElementRef: ref }), handleRefChange = useCallback(
5468
5407
  (el) => {
5469
- setRootElement(el), ref.current = el;
5408
+ ref.current = el, ref.current && registerElement && registerElement(ref.current);
5470
5409
  },
5471
- [setRootElement]
5410
+ [registerElement]
5472
5411
  );
5473
5412
  useEffect(() => {
5474
5413
  onItemSelect && onItemSelect(activeIndex);
5475
5414
  }, [activeIndex, onItemSelect]), useClickOutside(
5476
- useCallback(
5477
- (event) => isTopLayer && onClickOutside && onClickOutside(event),
5478
- [isTopLayer, onClickOutside]
5479
- ),
5480
- [rootElement]
5415
+ (event) => isTopLayer && onClickOutside && onClickOutside(event),
5416
+ () => [ref.current]
5481
5417
  ), useGlobalKeyDown(
5482
5418
  useCallback(
5483
5419
  (event) => {
@@ -5485,10 +5421,7 @@ const Root$5 = styled(Box)`
5485
5421
  },
5486
5422
  [isTopLayer, onEscape]
5487
5423
  )
5488
- ), useEffect(() => {
5489
- if (!(!rootElement || !registerElement))
5490
- return registerElement(rootElement);
5491
- }, [registerElement, rootElement]);
5424
+ );
5492
5425
  const value = useMemo(
5493
5426
  () => ({
5494
5427
  version: 0,
@@ -6164,7 +6097,7 @@ const CustomInline = styled(Inline)`
6164
6097
  }
6165
6098
  100% {
6166
6099
  width: 100%;
6167
- }
6100
+ }
6168
6101
  `, LOADING_BAR_HEIGHT = 2;
6169
6102
  function rootStyles(props) {
6170
6103
  const { color } = getTheme_v2$1(props.theme), loadingBarColor = color.button.default[props.tone].enabled.bg;
@@ -6862,6 +6795,7 @@ export {
6862
6795
  useForwardedRef,
6863
6796
  useGlobalKeyDown,
6864
6797
  useLayer,
6798
+ useMatchMedia,
6865
6799
  useMediaIndex,
6866
6800
  usePortal,
6867
6801
  usePrefersDark,