@sanity/ui 2.8.0 → 2.8.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.js CHANGED
@@ -126,8 +126,48 @@ function useArrayProp(val, defaultVal) {
126
126
  [__perf_hash__]
127
127
  );
128
128
  }
129
+ function _getElements(element, elementsArg) {
130
+ const ret = [element];
131
+ for (const el of elementsArg)
132
+ Array.isArray(el) ? ret.push(...el) : ret.push(el);
133
+ return ret.filter(Boolean);
134
+ }
129
135
  function useClickOutside(listener, elementsArg = EMPTY_ARRAY, boundaryElement) {
130
- const [legacyElement, setLegacyElement] = react.useState(null), onEvent = useEffectEvent.useEffectEvent((evt) => {
136
+ const [element, setElement] = react.useState(null), [elements, setElements] = react.useState(() => _getElements(element, elementsArg)), elementsRef = react.useRef(elements);
137
+ return react.useEffect(() => {
138
+ const prevElements = elementsRef.current, nextElements = _getElements(element, elementsArg);
139
+ if (prevElements.length !== nextElements.length) {
140
+ setElements(nextElements), elementsRef.current = nextElements;
141
+ return;
142
+ }
143
+ for (const el of prevElements)
144
+ if (!nextElements.includes(el)) {
145
+ setElements(nextElements), elementsRef.current = nextElements;
146
+ return;
147
+ }
148
+ for (const el of nextElements)
149
+ if (!prevElements.includes(el)) {
150
+ setElements(nextElements), elementsRef.current = nextElements;
151
+ return;
152
+ }
153
+ }, [element, elementsArg]), react.useEffect(() => {
154
+ if (!listener) return;
155
+ const handleWindowMouseDown = (evt) => {
156
+ const target = evt.target;
157
+ if (target instanceof Node && !(boundaryElement && !boundaryElement.contains(target))) {
158
+ for (const el of elements)
159
+ if (target === el || el.contains(target))
160
+ return;
161
+ listener(evt);
162
+ }
163
+ };
164
+ return window.addEventListener("mousedown", handleWindowMouseDown), () => {
165
+ window.removeEventListener("mousedown", handleWindowMouseDown);
166
+ };
167
+ }, [boundaryElement, listener, elements]), setElement;
168
+ }
169
+ function useClickOutsideEvent(listener, elementsArg = () => EMPTY_ARRAY, boundaryElement) {
170
+ const onEvent = useEffectEvent.useEffectEvent((evt) => {
131
171
  if (!listener)
132
172
  return;
133
173
  const target = evt.target;
@@ -136,20 +176,19 @@ function useClickOutside(listener, elementsArg = EMPTY_ARRAY, boundaryElement) {
136
176
  const resolvedBoundaryElement = typeof boundaryElement == "function" ? boundaryElement() : boundaryElement;
137
177
  if (resolvedBoundaryElement && !resolvedBoundaryElement.contains(target))
138
178
  return;
139
- const elements = (Array.isArray(elementsArg) ? [legacyElement, ...elementsArg] : elementsArg()).flat();
179
+ const elements = (Array.isArray(elementsArg) ? elementsArg : elementsArg()).flat();
140
180
  for (const el of elements)
141
181
  if (el && (target === el || el.contains(target)))
142
182
  return;
143
183
  listener(evt);
144
184
  }), hasListener = !!listener;
145
- if (react.useEffect(() => {
185
+ react.useEffect(() => {
146
186
  if (!hasListener) return;
147
187
  const handleEvent = (evt) => onEvent(evt);
148
188
  return document.addEventListener("mousedown", handleEvent), () => {
149
189
  document.removeEventListener("mousedown", handleEvent);
150
190
  };
151
- }, [hasListener, onEvent]), Array.isArray(elementsArg))
152
- return setLegacyElement;
191
+ }, [hasListener, onEvent]);
153
192
  }
154
193
  function useCustomValidity(ref, customValidity) {
155
194
  react.useEffect(() => {
@@ -5104,11 +5143,14 @@ const Root$7 = styledComponents.styled(Layer)(responsivePaddingStyle, dialogStyl
5104
5143
  [boundaryElement, isTopLayer, onClose, portalElement]
5105
5144
  )
5106
5145
  ), useClickOutside(
5107
- (event) => {
5108
- if (!isTopLayer || !onClickOutside) return;
5109
- const target = event.target;
5110
- target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5111
- },
5146
+ react.useCallback(
5147
+ (event) => {
5148
+ if (!isTopLayer || !onClickOutside) return;
5149
+ const target = event.target;
5150
+ target && !isTargetWithinScope(boundaryElement, portalElement, target) || onClickOutside();
5151
+ },
5152
+ [boundaryElement, isTopLayer, onClickOutside, portalElement]
5153
+ ),
5112
5154
  [rootElement]
5113
5155
  );
5114
5156
  const setRef = react.useCallback((el) => {
@@ -5445,7 +5487,13 @@ const Root$5 = styledComponents.styled(Box)`
5445
5487
  );
5446
5488
  react.useEffect(() => {
5447
5489
  onItemSelect && onItemSelect(activeIndex);
5448
- }, [activeIndex, onItemSelect]), useClickOutside((event) => isTopLayer && onClickOutside && onClickOutside(event), [rootElement]), useGlobalKeyDown(
5490
+ }, [activeIndex, onItemSelect]), useClickOutside(
5491
+ react.useCallback(
5492
+ (event) => isTopLayer && onClickOutside && onClickOutside(event),
5493
+ [isTopLayer, onClickOutside]
5494
+ ),
5495
+ [rootElement]
5496
+ ), useGlobalKeyDown(
5449
5497
  react.useCallback(
5450
5498
  (event) => {
5451
5499
  isTopLayer && event.key === "Escape" && (event.stopPropagation(), onEscape && onEscape());
@@ -6835,6 +6883,7 @@ exports.studioTheme = studioTheme;
6835
6883
  exports.useArrayProp = useArrayProp;
6836
6884
  exports.useBoundaryElement = useBoundaryElement;
6837
6885
  exports.useClickOutside = useClickOutside;
6886
+ exports.useClickOutsideEvent = useClickOutsideEvent;
6838
6887
  exports.useCustomValidity = useCustomValidity;
6839
6888
  exports.useDialog = useDialog;
6840
6889
  exports.useElementRect = useElementRect;