@sanity/ui 2.6.7-canary.0 → 2.6.7

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 (59) hide show
  1. package/dist/index.d.mts +15 -51
  2. package/dist/index.d.ts +15 -51
  3. package/dist/index.esm.js +186 -120
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +186 -119
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +186 -120
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/theme.d.mts +14 -14
  10. package/dist/theme.d.ts +14 -14
  11. package/dist/theme.esm.js.map +1 -1
  12. package/dist/theme.js.map +1 -1
  13. package/dist/theme.mjs.map +1 -1
  14. package/package.json +53 -46
  15. package/src/core/__workshop__/constants.ts +36 -36
  16. package/src/core/components/autocomplete/autocomplete.tsx +1 -1
  17. package/src/core/components/breadcrumbs/breadcrumbs.tsx +6 -15
  18. package/src/core/components/dialog/dialog.tsx +21 -12
  19. package/src/core/components/dialog/styles.ts +8 -8
  20. package/src/core/components/menu/menu.tsx +18 -11
  21. package/src/core/components/menu/menuButton.tsx +11 -11
  22. package/src/core/components/menu/menuContext.ts +1 -1
  23. package/src/core/components/menu/useMenuController.ts +17 -11
  24. package/src/core/components/tab/tab.tsx +8 -8
  25. package/src/core/components/tab/tabPanel.tsx +1 -1
  26. package/src/core/components/toast/styles.ts +1 -2
  27. package/src/core/components/toast/useToast.ts +0 -1
  28. package/src/core/components/tree/tree.tsx +0 -1
  29. package/src/core/components/tree/treeItem.tsx +0 -1
  30. package/src/core/helpers/focus.ts +0 -1
  31. package/src/core/helpers/scroll.ts +0 -1
  32. package/src/core/hooks/_internal/index.ts +1 -0
  33. package/src/core/hooks/_internal/useUnique.ts +34 -0
  34. package/src/core/hooks/index.ts +2 -3
  35. package/src/core/hooks/useClickOutside.ts +72 -38
  36. package/src/core/hooks/useElementSize.ts +0 -1
  37. package/src/core/hooks/useMediaIndex/useMediaIndex.ts +10 -2
  38. package/src/core/hooks/usePrefersDark.ts +55 -10
  39. package/src/core/hooks/usePrefersReducedMotion.ts +56 -10
  40. package/src/core/primitives/avatar/styles.ts +42 -42
  41. package/src/core/primitives/badge/styles.ts +2 -2
  42. package/src/core/primitives/button/styles.ts +4 -4
  43. package/src/core/primitives/inline/styles.ts +2 -2
  44. package/src/core/primitives/popover/__workshop__/AlignedStory.tsx +7 -9
  45. package/src/core/primitives/popover/constants.ts +4 -4
  46. package/src/core/primitives/stack/styles.ts +2 -2
  47. package/src/core/primitives/tooltip/__workshop__/customPortal.tsx +7 -9
  48. package/src/core/primitives/tooltip/constants.ts +4 -4
  49. package/src/core/primitives/tooltip/tooltip.tsx +49 -68
  50. package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupProvider.tsx +0 -1
  51. package/src/core/styles/font/responsiveFont.ts +8 -8
  52. package/src/core/theme/__workshop__/debug/story.tsx +11 -11
  53. package/src/core/utils/layer/layerProvider.tsx +0 -1
  54. package/src/core/utils/portal/__workshop__/named.tsx +8 -10
  55. package/src/core/utils/portal/portalProvider.tsx +13 -7
  56. package/src/theme/build/buildColorTheme.test.ts +13 -13
  57. package/src/theme/config/tokens/color/types.ts +14 -14
  58. package/src/theme/defaults/colorTokens.ts +36 -36
  59. package/src/core/hooks/useMatchMedia.ts +0 -46
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, useEffect, useState, useRef, 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, useRef, useEffect, createContext, useContext, useSyncExternalStore, useImperativeHandle, 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";
@@ -8,7 +8,6 @@ import Refractor from "react-refractor";
8
8
  import { detectOverflow, flip, offset, shift, arrow, hide, useFloating, autoUpdate } from "@floating-ui/react-dom";
9
9
  import { motion, AnimatePresence } from "framer-motion";
10
10
  import { createPortal } from "react-dom";
11
- import { useEffectEvent } from "use-effect-event";
12
11
  import { getTheme_v2 as getTheme_v2$1 } from "./_legacy/getTheme_v2.esm.js";
13
12
  const createColorTheme = createColorTheme$1, hexToRgb = hexToRgb$1, hslToRgb = hslToRgb$1, multiply = multiply$1, parseColor = parseColor$1, rgbToHex = rgbToHex$1, rgbToHsl = rgbToHsl$1, rgba = rgba$1, screen = screen$1, studioTheme = buildTheme(), EMPTY_ARRAY = [], EMPTY_RECORD = {}, POPOVER_MOTION_CONTENT_OPACITY_PROPERTY = "--motion-content-opacity", POPOVER_MOTION_PROPS = {
14
13
  initial: {
@@ -131,26 +130,45 @@ function useArrayProp(val, defaultVal) {
131
130
  [__perf_hash__]
132
131
  );
133
132
  }
133
+ function _getElements(element, elementsArg) {
134
+ const ret = [element];
135
+ for (const el of elementsArg)
136
+ Array.isArray(el) ? ret.push(...el) : ret.push(el);
137
+ return ret.filter(Boolean);
138
+ }
134
139
  function useClickOutside(listener, elementsArg = EMPTY_ARRAY, boundaryElement) {
135
- const eventHandler = useEffectEvent((evt) => {
136
- const target = evt.target;
137
- if (!(target instanceof Node) || boundaryElement && !boundaryElement.contains(target))
140
+ const [element, setElement] = useState(null), [elements, setElements] = useState(() => _getElements(element, elementsArg)), elementsRef = useRef(elements);
141
+ return useEffect(() => {
142
+ const prevElements = elementsRef.current, nextElements = _getElements(element, elementsArg);
143
+ if (prevElements.length !== nextElements.length) {
144
+ setElements(nextElements), elementsRef.current = nextElements;
138
145
  return;
139
- const elements = (Array.isArray(elementsArg) ? elementsArg : elementsArg()).flat();
140
- for (const el of elements)
141
- if (el && (target === el || el.contains(target)))
146
+ }
147
+ for (const el of prevElements)
148
+ if (!nextElements.includes(el)) {
149
+ setElements(nextElements), elementsRef.current = nextElements;
142
150
  return;
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]);
151
+ }
152
+ for (const el of nextElements)
153
+ if (!prevElements.includes(el)) {
154
+ setElements(nextElements), elementsRef.current = nextElements;
155
+ return;
156
+ }
157
+ }, [element, elementsArg]), useEffect(() => {
158
+ if (!listener) return;
159
+ const handleWindowMouseDown = (evt) => {
160
+ const target = evt.target;
161
+ if (target instanceof Node && !(boundaryElement && !boundaryElement.contains(target))) {
162
+ for (const el of elements)
163
+ if (target === el || el.contains(target))
164
+ return;
165
+ listener(evt);
166
+ }
167
+ };
168
+ return window.addEventListener("mousedown", handleWindowMouseDown), () => {
169
+ window.removeEventListener("mousedown", handleWindowMouseDown);
170
+ };
171
+ }, [boundaryElement, listener, elements]), setElement;
154
172
  }
155
173
  var resizeObservers = [], hasActiveObservations = function() {
156
174
  return resizeObservers.some(function(ro) {
@@ -485,27 +503,9 @@ function useElementRect(element) {
485
503
  const elementSize = useElementSize(element);
486
504
  return (elementSize == null ? void 0 : elementSize._contentRect) || null;
487
505
  }
488
- function useForwardedRef(ref) {
489
- const innerRef = useRef(null);
490
- return useImperativeHandle(ref, () => innerRef.current), innerRef;
491
- }
492
506
  function useGlobalKeyDown(onKeyDown) {
493
507
  return useEffect(() => (addEventListener("keydown", onKeyDown), () => removeEventListener("keydown", onKeyDown)), [onKeyDown]);
494
508
  }
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
- }
509
509
  function getGlobalScope() {
510
510
  if (typeof globalThis < "u") return globalThis;
511
511
  if (typeof window < "u") return window;
@@ -548,6 +548,7 @@ function useTheme() {
548
548
  function useTheme_v2() {
549
549
  return getTheme_v2(useTheme$1());
550
550
  }
551
+ const MEDIA_STORE_CACHE = /* @__PURE__ */ new WeakMap();
551
552
  function _getMediaQuery(media, index) {
552
553
  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)`;
553
554
  }
@@ -582,18 +583,57 @@ function _createMediaStore(media) {
582
583
  };
583
584
  } };
584
585
  }
585
- function getServerSnapshot() {
586
+ function getServerSnapshot$2() {
586
587
  return 0;
587
588
  }
588
589
  function useMediaIndex() {
589
- const { media } = useTheme_v2(), store = useMemo(() => _createMediaStore(media), [media]);
590
- return useSyncExternalStore(store.subscribe, store.getSnapshot, getServerSnapshot);
590
+ const { media } = useTheme_v2();
591
+ let store = MEDIA_STORE_CACHE.get(media);
592
+ return store || (store = _createMediaStore(media), MEDIA_STORE_CACHE.set(media, store)), useSyncExternalStore(store.subscribe, store.getSnapshot, getServerSnapshot$2);
593
+ }
594
+ let MEDIA_QUERY_CACHE$1;
595
+ function getMatchMedia$1() {
596
+ return MEDIA_QUERY_CACHE$1 || (MEDIA_QUERY_CACHE$1 = window.matchMedia("(prefers-color-scheme: dark)")), MEDIA_QUERY_CACHE$1;
597
+ }
598
+ function subscribe$2(onStoreChange) {
599
+ const matchMedia = getMatchMedia$1();
600
+ return matchMedia.addEventListener("change", onStoreChange), () => matchMedia.removeEventListener("change", onStoreChange);
601
+ }
602
+ function getSnapshot$1() {
603
+ return getMatchMedia$1().matches;
604
+ }
605
+ function getServerSnapshot$1() {
606
+ return !1;
607
+ }
608
+ function usePrefersDark() {
609
+ return useSyncExternalStore(subscribe$2, getSnapshot$1, getServerSnapshot$1);
610
+ }
611
+ let MEDIA_QUERY_CACHE;
612
+ function getMatchMedia() {
613
+ return MEDIA_QUERY_CACHE || (MEDIA_QUERY_CACHE = window.matchMedia("(prefers-reduced-motion: reduce)")), MEDIA_QUERY_CACHE;
614
+ }
615
+ function subscribe$1(onStoreChange) {
616
+ const matchMedia = getMatchMedia();
617
+ return matchMedia.addEventListener("change", onStoreChange), () => matchMedia.removeEventListener("change", onStoreChange);
618
+ }
619
+ function getSnapshot() {
620
+ return getMatchMedia().matches;
621
+ }
622
+ function getServerSnapshot() {
623
+ return !1;
591
624
  }
592
- function usePrefersDark(getServerSnapshot2 = () => !1) {
593
- return useMatchMedia("(prefers-color-scheme: dark)", getServerSnapshot2);
625
+ function usePrefersReducedMotion() {
626
+ return useSyncExternalStore(subscribe$1, getSnapshot, getServerSnapshot);
594
627
  }
595
- function usePrefersReducedMotion(getServerSnapshot2 = () => !1) {
596
- return useMatchMedia("(prefers-reduced-motion: reduce)", getServerSnapshot2);
628
+ function useForwardedRef(ref) {
629
+ const innerRef = useRef(null);
630
+ return useImperativeHandle(ref, () => innerRef.current), innerRef;
631
+ }
632
+ function useCustomValidity(ref, customValidity) {
633
+ useEffect(() => {
634
+ var _a;
635
+ (_a = ref.current) == null || _a.setCustomValidity(customValidity || "");
636
+ }, [customValidity, ref]);
597
637
  }
598
638
  function responsiveBorderStyle() {
599
639
  return [border, borderTop, borderRight, borderBottom, borderLeft];
@@ -3019,25 +3059,31 @@ function Portal(props) {
3019
3059
  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);
3020
3060
  return portalElement ? createPortal(children, portalElement) : null;
3021
3061
  }
3022
- function useMounted() {
3023
- return useSyncExternalStore(
3024
- subscribe,
3025
- () => !0,
3026
- () => !1
3027
- );
3062
+ function useUnique(value) {
3063
+ const valueRef = useRef(value);
3064
+ return _isEqual(valueRef.current, value) || (valueRef.current = value), valueRef.current;
3065
+ }
3066
+ function _isEqual(objA, objB) {
3067
+ if (!objA || !objB)
3068
+ return objA === objB;
3069
+ const keysA = Object.keys(objA), keysB = Object.keys(objB);
3070
+ return keysA.length !== keysB.length ? !1 : keysA.every((key2) => objA[key2] === objB[key2]);
3028
3071
  }
3029
- const subscribe = () => () => {
3030
- };
3031
3072
  function PortalProvider(props) {
3032
- const { boundaryElement, children, element, __unstable_elements: elements } = props, mounted = useMounted(), value = useMemo(() => ({
3073
+ const { boundaryElement, children, element, __unstable_elements: elementsProp } = props, elements = useUnique(elementsProp), fallbackElement = useSyncExternalStore(
3074
+ emptySubscribe$1,
3075
+ () => document.body,
3076
+ () => null
3077
+ ), value = useMemo(() => ({
3033
3078
  version: 0,
3034
3079
  boundaryElement: boundaryElement || null,
3035
- element: element || mounted ? document.body : null,
3080
+ element: element || fallbackElement,
3036
3081
  elements
3037
- }), [boundaryElement, element, elements, mounted]);
3082
+ }), [boundaryElement, element, elements, fallbackElement]);
3038
3083
  return /* @__PURE__ */ jsx(PortalContext.Provider, { value, children });
3039
3084
  }
3040
- const Root$i = styled.div`
3085
+ const emptySubscribe$1 = () => () => {
3086
+ }, Root$i = styled.div`
3041
3087
  display: block;
3042
3088
  width: 0;
3043
3089
  height: 0;
@@ -4292,6 +4338,7 @@ function TooltipDelayGroupProvider(props) {
4292
4338
  }
4293
4339
  const Root$a = styled(Layer)`
4294
4340
  pointer-events: none;
4341
+ max-width: ${({ $maxWidth }) => $maxWidth}px;
4295
4342
  `, Tooltip = forwardRef(function(props, forwardedRef) {
4296
4343
  var _a, _b, _c, _d, _e, _f, _g;
4297
4344
  const boundaryElementContext = useBoundaryElement(), { layer } = useTheme_v2(), {
@@ -4311,9 +4358,20 @@ const Root$a = styled(Layer)`
4311
4358
  zOffset = layer.tooltip.zOffset,
4312
4359
  delay,
4313
4360
  ...restProps
4314
- } = props, animate = usePrefersReducedMotion() ? !1 : _animate, fallbackPlacements = useArrayProp(fallbackPlacementsProp), ref = useRef(null), [referenceElement, setReferenceElement] = useState(null), arrowRef = useRef(null), rootBoundary = "viewport", [tooltipMaxWidth, setTooltipMaxWidth] = useState(0);
4361
+ } = props, animate = usePrefersReducedMotion() ? !1 : _animate, fallbackPlacements = useArrayProp(fallbackPlacementsProp), ref = useRef(null), [referenceElement, setReferenceElement] = useState(null), arrowRef = useRef(null), rootBoundary = "viewport";
4315
4362
  useImperativeHandle(forwardedRef, () => ref.current);
4316
- const portal = usePortal(), portalElement = typeof portalProp == "string" ? ((_c = portal.elements) == null ? void 0 : _c[portalProp]) || null : portal.element, middleware = useMemo(() => {
4363
+ const portal = usePortal(), portalElement = typeof portalProp == "string" ? ((_c = portal.elements) == null ? void 0 : _c[portalProp]) || null : portal.element, documentBodyOffsetWidth = useSyncExternalStore(
4364
+ emptySubscribe,
4365
+ () => document.body.offsetWidth,
4366
+ // We don't actually know what the width of the body is during SSR, so we'll just assume it's 800px or larger
4367
+ () => 800
4368
+ ), tooltipWidth = useMemo(() => {
4369
+ const availableWidths = [
4370
+ ...boundaryElement ? [boundaryElement.offsetWidth] : [],
4371
+ (portalElement == null ? void 0 : portalElement.offsetWidth) || documentBodyOffsetWidth
4372
+ ];
4373
+ return Math.min(...availableWidths) - DEFAULT_TOOLTIP_PADDING * 2;
4374
+ }, [boundaryElement, documentBodyOffsetWidth, portalElement == null ? void 0 : portalElement.offsetWidth]), middleware = useMemo(() => {
4317
4375
  const ret = [];
4318
4376
  return ret.push(
4319
4377
  flip({
@@ -4384,7 +4442,15 @@ const Root$a = styled(Layer)`
4384
4442
  },
4385
4443
  [childProp == null ? void 0 : childProp.props, handleIsOpenChange]
4386
4444
  );
4387
- useCloseOnMouseLeave({ handleIsOpenChange, referenceElement, showTooltip }), useEffect(() => {
4445
+ useEffect(() => {
4446
+ if (!showTooltip) return;
4447
+ function handleWindowMouseMove(event) {
4448
+ referenceElement && (referenceElement === event.target || event.target instanceof Node && referenceElement.contains(event.target) || (handleIsOpenChange(!1), window.removeEventListener("mousemove", handleWindowMouseMove)));
4449
+ }
4450
+ return window.addEventListener("mousemove", handleWindowMouseMove), () => {
4451
+ window.removeEventListener("mousemove", handleWindowMouseMove);
4452
+ };
4453
+ }, [showTooltip, referenceElement, handleIsOpenChange]), useEffect(() => {
4388
4454
  disabled && showTooltip && handleIsOpenChange(!1);
4389
4455
  }, [disabled, handleIsOpenChange, showTooltip]), useEffect(() => {
4390
4456
  !content && showTooltip && handleIsOpenChange(!1);
@@ -4396,13 +4462,7 @@ const Root$a = styled(Layer)`
4396
4462
  return window.addEventListener("keydown", handleWindowKeyDown), () => {
4397
4463
  window.removeEventListener("keydown", handleWindowKeyDown);
4398
4464
  };
4399
- }, [handleIsOpenChange, showTooltip]), useLayoutEffect(() => {
4400
- const availableWidths = [
4401
- ...boundaryElement ? [boundaryElement.offsetWidth] : [],
4402
- (portalElement == null ? void 0 : portalElement.offsetWidth) || document.body.offsetWidth
4403
- ];
4404
- setTooltipMaxWidth(Math.min(...availableWidths) - DEFAULT_TOOLTIP_PADDING * 2);
4405
- }, [boundaryElement, portalElement]);
4465
+ }, [handleIsOpenChange, showTooltip]);
4406
4466
  const setArrow = useCallback(
4407
4467
  (arrowEl) => {
4408
4468
  arrowRef.current = arrowEl, update();
@@ -4443,11 +4503,9 @@ const Root$a = styled(Layer)`
4443
4503
  "data-ui": "Tooltip",
4444
4504
  ...restProps,
4445
4505
  ref: setFloating,
4446
- style: {
4447
- ...floatingStyles,
4448
- maxWidth: tooltipMaxWidth > 0 ? `${tooltipMaxWidth}px` : void 0
4449
- },
4506
+ style: floatingStyles,
4450
4507
  zOffset,
4508
+ $maxWidth: tooltipWidth,
4451
4509
  children: /* @__PURE__ */ jsx(
4452
4510
  TooltipCard,
4453
4511
  {
@@ -4488,24 +4546,8 @@ const Root$a = styled(Layer)`
4488
4546
  ),
4489
4547
  child
4490
4548
  ] });
4491
- });
4492
- function useCloseOnMouseLeave({
4493
- handleIsOpenChange,
4494
- referenceElement,
4495
- showTooltip
4496
- }) {
4497
- const onMouseMove = useEffectEvent((target, teardown) => {
4498
- referenceElement && (referenceElement === target || target instanceof Node && referenceElement.contains(target) || (handleIsOpenChange(!1), teardown()));
4499
- });
4500
- useEffect(() => {
4501
- if (!showTooltip) return;
4502
- const handleMouseMove = (event) => {
4503
- onMouseMove(event.target, () => window.removeEventListener("mousemove", handleMouseMove));
4504
- };
4505
- return window.addEventListener("mousemove", handleMouseMove), () => window.removeEventListener("mousemove", handleMouseMove);
4506
- }, [onMouseMove, showTooltip]);
4507
- }
4508
- const Root$9 = styled.div`
4549
+ }), emptySubscribe = () => () => {
4550
+ }, Root$9 = styled.div`
4509
4551
  line-height: 0;
4510
4552
  `, ListBox = styled(Box)`
4511
4553
  & > ul {
@@ -4916,8 +4958,8 @@ const AUTOCOMPLETE_LISTBOX_IGNORE_KEYS = [
4916
4958
  appearance: none;
4917
4959
  margin: -4px;
4918
4960
  `, Breadcrumbs = forwardRef(function(props, ref) {
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]);
4961
+ 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), []);
4962
+ useClickOutside(collapse, [expandElement, popoverElement]);
4921
4963
  const rawItems = useMemo(() => Children.toArray(children).filter(isValidElement), [children]), items = useMemo(() => {
4922
4964
  const len = rawItems.length;
4923
4965
  if (maxLength && len > maxLength) {
@@ -4932,7 +4974,7 @@ const AUTOCOMPLETE_LISTBOX_IGNORE_KEYS = [
4932
4974
  open,
4933
4975
  placement: "top",
4934
4976
  portal: !0,
4935
- ref: popoverElementRef,
4977
+ ref: setPopoverElement,
4936
4978
  children: /* @__PURE__ */ jsx(
4937
4979
  ExpandButton,
4938
4980
  {
@@ -4940,7 +4982,7 @@ const AUTOCOMPLETE_LISTBOX_IGNORE_KEYS = [
4940
4982
  mode: "bleed",
4941
4983
  onClick: open ? collapse : expand,
4942
4984
  padding: 1,
4943
- ref: expandElementRef,
4985
+ ref: setExpandElement,
4944
4986
  selected: open,
4945
4987
  text: "\u2026"
4946
4988
  }
@@ -5065,8 +5107,8 @@ const Root$7 = styled(Layer)(responsivePaddingStyle, dialogStyle, responsiveDial
5065
5107
  scheme,
5066
5108
  shadow: shadowProp,
5067
5109
  width: widthProp
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(
5110
+ } = 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;
5111
+ useImperativeHandle(forwardedRef, () => ref.current), useImperativeHandle(
5070
5112
  forwardedContentRef,
5071
5113
  () => contentRef.current
5072
5114
  ), useEffect(() => {
@@ -5081,13 +5123,20 @@ const Root$7 = styled(Layer)(responsivePaddingStyle, dialogStyle, responsiveDial
5081
5123
  [boundaryElement, isTopLayer, onClose, portalElement]
5082
5124
  )
5083
5125
  ), useClickOutside(
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: [
5126
+ useCallback(
5127
+ (event) => {
5128
+ if (!isTopLayer || !onClickOutside) return;
5129
+ const target = event.target;
5130
+ target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5131
+ },
5132
+ [boundaryElement, isTopLayer, onClickOutside, portalElement]
5133
+ ),
5134
+ [rootElement]
5135
+ );
5136
+ const setRef = useCallback((el) => {
5137
+ setRootElement(el), ref.current = el;
5138
+ }, []);
5139
+ return /* @__PURE__ */ jsx(DialogContainer, { "data-ui": "DialogCard", width, children: /* @__PURE__ */ jsx(DialogCardRoot, { radius, ref: setRef, scheme, shadow, children: /* @__PURE__ */ jsxs(DialogLayout, { direction: "column", children: [
5091
5140
  showHeader && /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsxs(Flex, { align: "center", padding: 3, children: [
5092
5141
  /* @__PURE__ */ jsx(Box, { flex: 1, padding: 2, children: header && /* @__PURE__ */ jsx(Text, { id: labelId, size: 1, weight: "semibold", children: header }) }),
5093
5142
  showCloseButton && /* @__PURE__ */ jsx(Box, { flex: "none", children: /* @__PURE__ */ jsx(
@@ -5265,13 +5314,13 @@ function _sortElements(rootElement, elements) {
5265
5314
  elements.sort(_sort);
5266
5315
  }
5267
5316
  function useMenuController(props) {
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) => {
5317
+ 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) => {
5269
5318
  _setActiveIndex(nextActiveIndex), activeIndexRef.current = nextActiveIndex;
5270
5319
  }, []), mount = useCallback(
5271
5320
  (element, selected) => {
5272
5321
  if (!element) return () => {
5273
5322
  };
5274
- if (elementsRef.current.indexOf(element) === -1 && (elementsRef.current.push(element), _sortElements(rootElementRef.current, elementsRef.current)), selected) {
5323
+ if (elementsRef.current.indexOf(element) === -1 && (elementsRef.current.push(element), _sortElements(rootElement, elementsRef.current)), selected) {
5275
5324
  const selectedIndex = elementsRef.current.indexOf(element);
5276
5325
  setActiveIndex(selectedIndex);
5277
5326
  }
@@ -5280,7 +5329,7 @@ function useMenuController(props) {
5280
5329
  idx > -1 && elementsRef.current.splice(idx, 1);
5281
5330
  };
5282
5331
  },
5283
- [rootElementRef, setActiveIndex]
5332
+ [rootElement, setActiveIndex]
5284
5333
  ), handleKeyDown = useCallback(
5285
5334
  (event) => {
5286
5335
  if (event.key === "Tab") {
@@ -5335,13 +5384,13 @@ function useMenuController(props) {
5335
5384
  },
5336
5385
  [setActiveIndex]
5337
5386
  ), handleItemMouseLeave = useCallback(() => {
5338
- var _a;
5339
- setActiveIndex(-2), (_a = rootElementRef.current) == null || _a.focus();
5340
- }, [rootElementRef, setActiveIndex]);
5387
+ setActiveIndex(-2), rootElement == null || rootElement.focus();
5388
+ }, [setActiveIndex, rootElement]);
5341
5389
  return useEffect(() => {
5342
5390
  if (!mounted) return;
5343
5391
  const rafId = window.requestAnimationFrame(() => {
5344
- if (activeIndex === -1) {
5392
+ const _activeIndex = activeIndexRef.current;
5393
+ if (_activeIndex === -1) {
5345
5394
  if (shouldFocus === "first") {
5346
5395
  const el = _getFocusableElements(elementsRef.current)[0];
5347
5396
  if (el) {
@@ -5358,7 +5407,7 @@ function useMenuController(props) {
5358
5407
  }
5359
5408
  return;
5360
5409
  }
5361
- const element = elementsRef.current[activeIndex] || null;
5410
+ const element = elementsRef.current[_activeIndex] || null;
5362
5411
  element == null || element.focus();
5363
5412
  });
5364
5413
  return () => {
@@ -5370,7 +5419,9 @@ function useMenuController(props) {
5370
5419
  handleItemMouseEnter,
5371
5420
  handleItemMouseLeave,
5372
5421
  handleKeyDown,
5373
- mount
5422
+ mount,
5423
+ rootElement,
5424
+ setRootElement
5374
5425
  };
5375
5426
  }
5376
5427
  const Root$5 = styled(Box)`
@@ -5402,18 +5453,23 @@ const Root$5 = styled(Box)`
5402
5453
  handleItemMouseEnter,
5403
5454
  handleItemMouseLeave,
5404
5455
  handleKeyDown,
5405
- mount
5406
- } = useMenuController({ onKeyDown, originElement, shouldFocus, rootElementRef: ref }), handleRefChange = useCallback(
5456
+ mount,
5457
+ rootElement,
5458
+ setRootElement
5459
+ } = useMenuController({ onKeyDown, originElement, shouldFocus }), handleRefChange = useCallback(
5407
5460
  (el) => {
5408
- ref.current = el, ref.current && registerElement && registerElement(ref.current);
5461
+ setRootElement(el), ref.current = el;
5409
5462
  },
5410
- [registerElement]
5463
+ [setRootElement]
5411
5464
  );
5412
5465
  useEffect(() => {
5413
5466
  onItemSelect && onItemSelect(activeIndex);
5414
5467
  }, [activeIndex, onItemSelect]), useClickOutside(
5415
- (event) => isTopLayer && onClickOutside && onClickOutside(event),
5416
- () => [ref.current]
5468
+ useCallback(
5469
+ (event) => isTopLayer && onClickOutside && onClickOutside(event),
5470
+ [isTopLayer, onClickOutside]
5471
+ ),
5472
+ [rootElement]
5417
5473
  ), useGlobalKeyDown(
5418
5474
  useCallback(
5419
5475
  (event) => {
@@ -5421,7 +5477,10 @@ const Root$5 = styled(Box)`
5421
5477
  },
5422
5478
  [isTopLayer, onEscape]
5423
5479
  )
5424
- );
5480
+ ), useEffect(() => {
5481
+ if (!(!rootElement || !registerElement))
5482
+ return registerElement(rootElement);
5483
+ }, [registerElement, rootElement]);
5425
5484
  const value = useMemo(
5426
5485
  () => ({
5427
5486
  version: 0,
@@ -6097,7 +6156,7 @@ const CustomInline = styled(Inline)`
6097
6156
  }
6098
6157
  100% {
6099
6158
  width: 100%;
6100
- }
6159
+ }
6101
6160
  `, LOADING_BAR_HEIGHT = 2;
6102
6161
  function rootStyles(props) {
6103
6162
  const { color } = getTheme_v2$1(props.theme), loadingBarColor = color.button.default[props.tone].enabled.bg;
@@ -6183,7 +6242,15 @@ function Toast(props) {
6183
6242
  }
6184
6243
  );
6185
6244
  }
6186
- const key$1 = Symbol.for("@sanity/ui/context/toast"), ToastContext = createGlobalScopedContext(key$1, null), Root$1 = styled(Layer)`
6245
+ function useMounted() {
6246
+ return useSyncExternalStore(
6247
+ subscribe,
6248
+ () => !0,
6249
+ () => !1
6250
+ );
6251
+ }
6252
+ const subscribe = () => () => {
6253
+ }, key$1 = Symbol.for("@sanity/ui/context/toast"), ToastContext = createGlobalScopedContext(key$1, null), Root$1 = styled(Layer)`
6187
6254
  position: fixed;
6188
6255
  top: 0;
6189
6256
  left: 0;
@@ -6795,7 +6862,6 @@ export {
6795
6862
  useForwardedRef,
6796
6863
  useGlobalKeyDown,
6797
6864
  useLayer,
6798
- useMatchMedia,
6799
6865
  useMediaIndex,
6800
6866
  usePortal,
6801
6867
  usePrefersDark,