@jobber/components 9.6.1 → 9.6.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/Autocomplete/index.cjs +2 -0
- package/dist/Autocomplete/index.mjs +2 -0
- package/dist/Autocomplete-cjs.js +5 -4
- package/dist/Autocomplete-es.js +2 -1
- package/dist/Card/index.cjs +2 -1
- package/dist/Card/index.mjs +2 -1
- package/dist/Chip/index.cjs +2 -0
- package/dist/Chip/index.mjs +2 -0
- package/dist/Chips/InternalChipDismissible/hooks/index.cjs +2 -0
- package/dist/Chips/InternalChipDismissible/hooks/index.mjs +2 -0
- package/dist/Chips/InternalChipDismissible/index.cjs +2 -0
- package/dist/Chips/InternalChipDismissible/index.mjs +2 -0
- package/dist/Chips/index.cjs +2 -0
- package/dist/Chips/index.mjs +2 -0
- package/dist/Combobox/index.cjs +4 -2
- package/dist/Combobox/index.mjs +4 -2
- package/dist/{ComboboxSeparator-cjs.js → ComboboxChipRemove-cjs.js} +455 -501
- package/dist/{ComboboxSeparator-es.js → ComboboxChipRemove-es.js} +456 -500
- package/dist/ComboboxPrimitive-cjs.js +30 -29
- package/dist/ComboboxPrimitive-es.js +3 -2
- package/dist/ConfirmationModal/index.cjs +2 -0
- package/dist/ConfirmationModal/index.mjs +2 -0
- package/dist/DataDump/index.cjs +2 -1
- package/dist/DataDump/index.mjs +2 -1
- package/dist/DataList/components/DataListActions/index.cjs +2 -0
- package/dist/DataList/components/DataListActions/index.mjs +2 -0
- package/dist/DataList/components/DataListBulkActions/index.cjs +2 -0
- package/dist/DataList/components/DataListBulkActions/index.mjs +2 -0
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +2 -0
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +2 -0
- package/dist/DataList/components/DataListFilters/index.cjs +2 -0
- package/dist/DataList/components/DataListFilters/index.mjs +2 -0
- package/dist/DataList/components/DataListHeader/index.cjs +2 -0
- package/dist/DataList/components/DataListHeader/index.mjs +2 -0
- package/dist/DataList/components/DataListItem/index.cjs +2 -0
- package/dist/DataList/components/DataListItem/index.mjs +2 -0
- package/dist/DataList/components/DataListItemActions/index.cjs +2 -0
- package/dist/DataList/components/DataListItemActions/index.mjs +2 -0
- package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +2 -0
- package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +2 -0
- package/dist/DataList/components/DataListItems/index.cjs +2 -0
- package/dist/DataList/components/DataListItems/index.mjs +2 -0
- package/dist/DataList/components/DataListLayout/index.cjs +2 -0
- package/dist/DataList/components/DataListLayout/index.mjs +2 -0
- package/dist/DataList/components/DataListLayoutActions/index.cjs +2 -0
- package/dist/DataList/components/DataListLayoutActions/index.mjs +2 -0
- package/dist/DataList/index.cjs +2 -0
- package/dist/DataList/index.mjs +2 -0
- package/dist/DatePicker/index.cjs +2 -0
- package/dist/DatePicker/index.mjs +2 -0
- package/dist/DatePicker-cjs.js +5 -4
- package/dist/DatePicker-es.js +2 -1
- package/dist/Dialog/index.cjs +2 -1
- package/dist/Dialog/index.mjs +2 -1
- package/dist/DrawerDescription-cjs.js +99 -268
- package/dist/DrawerDescription-es.js +103 -270
- package/dist/DrawerTitle-cjs.js +6 -2
- package/dist/DrawerTitle-es.js +7 -3
- package/dist/FieldDescription-cjs.js +181 -184
- package/dist/FieldDescription-es.js +184 -187
- package/dist/FilterPicker/components/FilterPickerActivator/index.cjs +2 -0
- package/dist/FilterPicker/components/FilterPickerActivator/index.mjs +2 -0
- package/dist/FilterPicker/components/FilterPickerContent/index.cjs +2 -0
- package/dist/FilterPicker/components/FilterPickerContent/index.mjs +2 -0
- package/dist/FilterPicker/components/FilterPickerTrigger/index.cjs +2 -0
- package/dist/FilterPicker/components/FilterPickerTrigger/index.mjs +2 -0
- package/dist/FilterPicker/index.cjs +2 -0
- package/dist/FilterPicker/index.mjs +2 -0
- package/dist/FilterPickerContent-cjs.js +5 -4
- package/dist/FilterPickerContent-es.js +2 -1
- package/dist/FormatFile/index.cjs +2 -0
- package/dist/FormatFile/index.mjs +2 -0
- package/dist/Gallery/index.cjs +2 -0
- package/dist/Gallery/index.mjs +2 -0
- package/dist/InputDate/index.cjs +2 -0
- package/dist/InputDate/index.mjs +2 -0
- package/dist/InputNumber/index.cjs +2 -1
- package/dist/InputNumber/index.mjs +2 -1
- package/dist/LightBox/index.cjs +2 -0
- package/dist/LightBox/index.mjs +2 -0
- package/dist/Menu/index.cjs +2 -1
- package/dist/Menu/index.mjs +2 -1
- package/dist/Menu-cjs.js +5 -4
- package/dist/Menu-es.js +2 -1
- package/dist/MenuSubmenuTrigger-cjs.js +164 -206
- package/dist/MenuSubmenuTrigger-es.js +152 -194
- package/dist/Modal/index.cjs +2 -0
- package/dist/Modal/index.mjs +3 -1
- package/dist/NumberFieldInput-cjs.js +308 -187
- package/dist/NumberFieldInput-es.js +308 -187
- package/dist/Page/index.cjs +2 -1
- package/dist/Page/index.mjs +2 -1
- package/dist/Popover/index.cjs +2 -0
- package/dist/Popover/index.mjs +2 -0
- package/dist/Popover-cjs.js +8 -7
- package/dist/Popover-es.js +2 -1
- package/dist/ScrollAreaViewport-cjs.js +1093 -747
- package/dist/ScrollAreaViewport-es.js +1081 -734
- package/dist/Select/index.cjs +2 -1
- package/dist/Select/index.mjs +2 -1
- package/dist/SelectGroupLabel-cjs.js +306 -207
- package/dist/SelectGroupLabel-es.js +302 -203
- package/dist/Tooltip/index.cjs +2 -0
- package/dist/Tooltip/index.mjs +2 -0
- package/dist/Tooltip-cjs.js +7 -6
- package/dist/Tooltip-es.js +2 -1
- package/dist/dialogReturnFocus-cjs.js +1 -1
- package/dist/dialogReturnFocus-es.js +2 -2
- package/dist/floating-ui.react-cjs.js +192 -2564
- package/dist/floating-ui.react-dom-cjs.js +2103 -0
- package/dist/floating-ui.react-dom-es.js +2072 -0
- package/dist/floating-ui.react-es.js +156 -2519
- package/dist/floating-ui.utils-cjs.js +342 -0
- package/dist/floating-ui.utils-es.js +300 -0
- package/dist/index.cjs +4 -3
- package/dist/index.mjs +4 -3
- package/dist/primitives/BottomSheet/index.cjs +1 -1
- package/dist/primitives/BottomSheet/index.mjs +1 -1
- package/dist/primitives/ComboboxPrimitive/index.cjs +4 -2
- package/dist/primitives/ComboboxPrimitive/index.mjs +4 -2
- package/dist/primitives/SelectPrimitive/index.cjs +2 -0
- package/dist/primitives/SelectPrimitive/index.mjs +2 -0
- package/dist/primitives/index.cjs +3 -2
- package/dist/primitives/index.mjs +3 -2
- package/dist/scrollEdges-cjs.js +11 -1
- package/dist/scrollEdges-es.js +11 -1
- package/dist/unstyledPrimitives/index.cjs +478 -720
- package/dist/unstyledPrimitives/index.mjs +421 -663
- package/dist/useCompositeListItem-cjs.js +361 -2108
- package/dist/useCompositeListItem-es.js +331 -2076
- package/dist/useLabel-cjs.js +3 -2
- package/dist/useLabel-es.js +3 -2
- package/dist/useRenderElement-cjs.js +7 -9
- package/dist/useRenderElement-es.js +7 -9
- package/dist/useScrollLock-cjs.js +344 -819
- package/dist/useScrollLock-es.js +296 -732
- package/dist/useScrollToActive-cjs.js +5 -4
- package/dist/useScrollToActive-es.js +2 -1
- package/package.json +3 -3
- package/dist/scrollable-cjs.js +0 -58
- package/dist/scrollable-es.js +0 -54
package/dist/useScrollLock-es.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as isShadowRoot, i as isHTMLElement, b as isElement, h as getComputedStyle, f as floor, g as getNodeName, c as isNode, K as getWindow, d as isLastTraversableNode, e as getParentNode, I as isOverflowElement } from './floating-ui.utils-es.js';
|
|
4
|
+
import { a as useRefWithInit, f as formatErrorMessage, i as isReactVersionAtLeast, N as NOOP, E as EMPTY_OBJECT, u as useRenderElement, b as useMergedRefs, m as mergeProps, d as makeEventPreventable } from './useRenderElement-es.js';
|
|
4
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
6
|
import * as ReactDOM from 'react-dom';
|
|
6
7
|
|
|
@@ -82,6 +83,14 @@ function serializeToDevModeString(input) {
|
|
|
82
83
|
const noop = () => {};
|
|
83
84
|
const useIsoLayoutEffect = typeof document !== 'undefined' ? React.useLayoutEffect : noop;
|
|
84
85
|
|
|
86
|
+
function useOnFirstRender(fn) {
|
|
87
|
+
const ref = React.useRef(true);
|
|
88
|
+
if (ref.current) {
|
|
89
|
+
ref.current = false;
|
|
90
|
+
fn();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
85
94
|
/**
|
|
86
95
|
* A clone of the React namespace for reading APIs that may be missing in older
|
|
87
96
|
* supported React versions. Bundlers can rewrite direct `React.someNewApi`
|
|
@@ -180,6 +189,87 @@ const visuallyHiddenInput = {
|
|
|
180
189
|
position: 'absolute'
|
|
181
190
|
};
|
|
182
191
|
|
|
192
|
+
/**
|
|
193
|
+
* The NoOptionalParams type is a utility type that checks if a function has optional or default parameters.
|
|
194
|
+
* If the function has optional or default parameters, it returns a string literal type with an error message.
|
|
195
|
+
* Otherwise, it returns the original function type.
|
|
196
|
+
*
|
|
197
|
+
* This is used to enforce that the combiner function passed to createSelector does not have optional or default parameters,
|
|
198
|
+
* as memoization relies on the Function.length property, which does not account for optional or default parameters.
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Creates a selector function that can be used to derive values from the store's state.
|
|
203
|
+
*
|
|
204
|
+
* The combiner function can have up to three additional parameters, but it **cannot have optional or default parameters**.
|
|
205
|
+
*
|
|
206
|
+
* This function accepts up to six functions and combines them into a single selector function.
|
|
207
|
+
* The resulting selector will take the state from the combined selectors and any additional parameters required by the combiner.
|
|
208
|
+
*
|
|
209
|
+
* The return type of the resulting selector is determined by the return type of the combiner function.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* const selector = createSelector(
|
|
213
|
+
* (state) => state.disabled
|
|
214
|
+
* );
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* const selector = createSelector(
|
|
218
|
+
* (state) => state.disabled,
|
|
219
|
+
* (state) => state.open,
|
|
220
|
+
* (disabled, open) => ({ disabled, open })
|
|
221
|
+
* );
|
|
222
|
+
*/
|
|
223
|
+
/* eslint-disable id-denylist */
|
|
224
|
+
const createSelector = (a, b, c, d, e, f, ...other) => {
|
|
225
|
+
if (other.length > 0) {
|
|
226
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Unsupported number of selectors' : formatErrorMessage(1));
|
|
227
|
+
}
|
|
228
|
+
let selector;
|
|
229
|
+
if (a && b && c && d && e && f) {
|
|
230
|
+
selector = (state, a1, a2, a3) => {
|
|
231
|
+
const va = a(state, a1, a2, a3);
|
|
232
|
+
const vb = b(state, a1, a2, a3);
|
|
233
|
+
const vc = c(state, a1, a2, a3);
|
|
234
|
+
const vd = d(state, a1, a2, a3);
|
|
235
|
+
const ve = e(state, a1, a2, a3);
|
|
236
|
+
return f(va, vb, vc, vd, ve, a1, a2, a3);
|
|
237
|
+
};
|
|
238
|
+
} else if (a && b && c && d && e) {
|
|
239
|
+
selector = (state, a1, a2, a3) => {
|
|
240
|
+
const va = a(state, a1, a2, a3);
|
|
241
|
+
const vb = b(state, a1, a2, a3);
|
|
242
|
+
const vc = c(state, a1, a2, a3);
|
|
243
|
+
const vd = d(state, a1, a2, a3);
|
|
244
|
+
return e(va, vb, vc, vd, a1, a2, a3);
|
|
245
|
+
};
|
|
246
|
+
} else if (a && b && c && d) {
|
|
247
|
+
selector = (state, a1, a2, a3) => {
|
|
248
|
+
const va = a(state, a1, a2, a3);
|
|
249
|
+
const vb = b(state, a1, a2, a3);
|
|
250
|
+
const vc = c(state, a1, a2, a3);
|
|
251
|
+
return d(va, vb, vc, a1, a2, a3);
|
|
252
|
+
};
|
|
253
|
+
} else if (a && b && c) {
|
|
254
|
+
selector = (state, a1, a2, a3) => {
|
|
255
|
+
const va = a(state, a1, a2, a3);
|
|
256
|
+
const vb = b(state, a1, a2, a3);
|
|
257
|
+
return c(va, vb, a1, a2, a3);
|
|
258
|
+
};
|
|
259
|
+
} else if (a && b) {
|
|
260
|
+
selector = (state, a1, a2, a3) => {
|
|
261
|
+
const va = a(state, a1, a2, a3);
|
|
262
|
+
return b(va, a1, a2, a3);
|
|
263
|
+
};
|
|
264
|
+
} else if (a) {
|
|
265
|
+
selector = a;
|
|
266
|
+
} else {
|
|
267
|
+
throw /* minify-error-disabled */new Error('Missing arguments');
|
|
268
|
+
}
|
|
269
|
+
return selector;
|
|
270
|
+
};
|
|
271
|
+
/* eslint-enable id-denylist */
|
|
272
|
+
|
|
183
273
|
var shim = {exports: {}};
|
|
184
274
|
|
|
185
275
|
var useSyncExternalStoreShim_production = {};
|
|
@@ -587,41 +677,6 @@ function getInstance() {
|
|
|
587
677
|
function register(hook) {
|
|
588
678
|
hooks.push(hook);
|
|
589
679
|
}
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* Wraps a component function to enable performance optimizations for internal hooks.
|
|
593
|
-
*
|
|
594
|
-
* **Performance Optimization:**
|
|
595
|
-
* Components wrapped with `fastComponent` have access to a shared "instance" context that enables
|
|
596
|
-
* specialized hook implementations to batch operations and reduce overhead. The wrapper creates a
|
|
597
|
-
* stable instance object that persists across renders, sets it as the current context, calls
|
|
598
|
-
* registered hooks before and after rendering, then clears the context. The primary benefit is
|
|
599
|
-
* with `useStore`, where multiple store subscriptions within the same component are collapsed into
|
|
600
|
-
* a single `useSyncExternalStore` subscription per store, significantly reducing re-render overhead.
|
|
601
|
-
* This optimization is only active on React 19+; on earlier versions `useStore` falls back to a
|
|
602
|
-
* separate subscription per call.
|
|
603
|
-
*
|
|
604
|
-
* **Requirements:**
|
|
605
|
-
* - The component function should follow standard React component patterns
|
|
606
|
-
* - `useStore` calls must keep a stable order and count across renders, as batched hooks are
|
|
607
|
-
* matched by call index
|
|
608
|
-
* - Do not rely on the instance context outside of specialized hooks
|
|
609
|
-
*
|
|
610
|
-
* @param fn - The component function to wrap
|
|
611
|
-
* @returns A wrapped component with the same signature as the input function
|
|
612
|
-
*
|
|
613
|
-
* @example
|
|
614
|
-
* ```tsx
|
|
615
|
-
* // Wrapping a component to enable optimized useStore batching
|
|
616
|
-
* export const TooltipRoot = fastComponent(function TooltipRoot(props) {
|
|
617
|
-
* // These useStore calls share a single subscription
|
|
618
|
-
* const open = useStore(store, (state) => state.open);
|
|
619
|
-
* const disabled = useStore(store, (state) => state.disabled);
|
|
620
|
-
* const value = useStore(store, (state) => state.value);
|
|
621
|
-
* // ...
|
|
622
|
-
* });
|
|
623
|
-
* ```
|
|
624
|
-
*/
|
|
625
680
|
function fastComponent(fn) {
|
|
626
681
|
const FastComponent = (props, forwardedRef) => {
|
|
627
682
|
const instance = useRefWithInit(createInstance).current;
|
|
@@ -644,31 +699,6 @@ function fastComponent(fn) {
|
|
|
644
699
|
FastComponent.displayName = fn.displayName || fn.name;
|
|
645
700
|
return FastComponent;
|
|
646
701
|
}
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* Wraps a component function with ref forwarding to enable performance optimizations for internal hooks.
|
|
650
|
-
*
|
|
651
|
-
* This is a convenience wrapper that combines `fastComponent` with `React.forwardRef`, enabling
|
|
652
|
-
* both performance optimizations and proper ref forwarding. See `fastComponent` for details on
|
|
653
|
-
* the performance benefits.
|
|
654
|
-
*
|
|
655
|
-
* @param fn - The component function that accepts props and a forwarded ref
|
|
656
|
-
* @returns A wrapped component with ref forwarding enabled
|
|
657
|
-
*
|
|
658
|
-
* @example
|
|
659
|
-
* ```tsx
|
|
660
|
-
* // Wrapping a component with ref forwarding and optimized hooks
|
|
661
|
-
* export const TooltipTrigger = fastComponentRef(function TooltipTrigger(
|
|
662
|
-
* props,
|
|
663
|
-
* forwardedRef
|
|
664
|
-
* ) {
|
|
665
|
-
* const store = useContext(TooltipContext);
|
|
666
|
-
* const open = useStore(store, (state) => state.open);
|
|
667
|
-
* // ... component logic with ref
|
|
668
|
-
* return <button ref={forwardedRef} {...props} />;
|
|
669
|
-
* });
|
|
670
|
-
* ```
|
|
671
|
-
*/
|
|
672
702
|
function fastComponentRef(fn) {
|
|
673
703
|
return /*#__PURE__*/React.forwardRef(fastComponent(fn));
|
|
674
704
|
}
|
|
@@ -1084,170 +1114,6 @@ class ReactStore extends Store {
|
|
|
1084
1114
|
}
|
|
1085
1115
|
}
|
|
1086
1116
|
|
|
1087
|
-
function hasWindow() {
|
|
1088
|
-
return typeof window !== 'undefined';
|
|
1089
|
-
}
|
|
1090
|
-
function getNodeName(node) {
|
|
1091
|
-
if (isNode(node)) {
|
|
1092
|
-
return (node.nodeName || '').toLowerCase();
|
|
1093
|
-
}
|
|
1094
|
-
// Mocked nodes in testing environments may not be instances of Node. By
|
|
1095
|
-
// returning `#document` an infinite loop won't occur.
|
|
1096
|
-
// https://github.com/floating-ui/floating-ui/issues/2317
|
|
1097
|
-
return '#document';
|
|
1098
|
-
}
|
|
1099
|
-
function getWindow(node) {
|
|
1100
|
-
var _node$ownerDocument;
|
|
1101
|
-
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
|
|
1102
|
-
}
|
|
1103
|
-
function getDocumentElement(node) {
|
|
1104
|
-
var _ref;
|
|
1105
|
-
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
|
|
1106
|
-
}
|
|
1107
|
-
function isNode(value) {
|
|
1108
|
-
if (!hasWindow()) {
|
|
1109
|
-
return false;
|
|
1110
|
-
}
|
|
1111
|
-
return value instanceof Node || value instanceof getWindow(value).Node;
|
|
1112
|
-
}
|
|
1113
|
-
function isElement(value) {
|
|
1114
|
-
if (!hasWindow()) {
|
|
1115
|
-
return false;
|
|
1116
|
-
}
|
|
1117
|
-
return value instanceof Element || value instanceof getWindow(value).Element;
|
|
1118
|
-
}
|
|
1119
|
-
function isHTMLElement(value) {
|
|
1120
|
-
if (!hasWindow()) {
|
|
1121
|
-
return false;
|
|
1122
|
-
}
|
|
1123
|
-
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
|
|
1124
|
-
}
|
|
1125
|
-
function isShadowRoot(value) {
|
|
1126
|
-
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
|
|
1127
|
-
return false;
|
|
1128
|
-
}
|
|
1129
|
-
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
|
|
1130
|
-
}
|
|
1131
|
-
function isOverflowElement(element) {
|
|
1132
|
-
const {
|
|
1133
|
-
overflow,
|
|
1134
|
-
overflowX,
|
|
1135
|
-
overflowY,
|
|
1136
|
-
display
|
|
1137
|
-
} = getComputedStyle(element);
|
|
1138
|
-
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';
|
|
1139
|
-
}
|
|
1140
|
-
function isTableElement(element) {
|
|
1141
|
-
return /^(table|td|th)$/.test(getNodeName(element));
|
|
1142
|
-
}
|
|
1143
|
-
function isTopLayer(element) {
|
|
1144
|
-
try {
|
|
1145
|
-
if (element.matches(':popover-open')) {
|
|
1146
|
-
return true;
|
|
1147
|
-
}
|
|
1148
|
-
} catch (_e) {
|
|
1149
|
-
// no-op
|
|
1150
|
-
}
|
|
1151
|
-
try {
|
|
1152
|
-
return element.matches(':modal');
|
|
1153
|
-
} catch (_e) {
|
|
1154
|
-
return false;
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
const willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
|
|
1158
|
-
const containRe = /paint|layout|strict|content/;
|
|
1159
|
-
const isNotNone = value => !!value && value !== 'none';
|
|
1160
|
-
let isWebKitValue;
|
|
1161
|
-
function isContainingBlock(elementOrCss) {
|
|
1162
|
-
const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
|
|
1163
|
-
|
|
1164
|
-
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
|
|
1165
|
-
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
|
|
1166
|
-
return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');
|
|
1167
|
-
}
|
|
1168
|
-
function getContainingBlock(element) {
|
|
1169
|
-
let currentNode = getParentNode(element);
|
|
1170
|
-
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
|
|
1171
|
-
if (isContainingBlock(currentNode)) {
|
|
1172
|
-
return currentNode;
|
|
1173
|
-
} else if (isTopLayer(currentNode)) {
|
|
1174
|
-
return null;
|
|
1175
|
-
}
|
|
1176
|
-
currentNode = getParentNode(currentNode);
|
|
1177
|
-
}
|
|
1178
|
-
return null;
|
|
1179
|
-
}
|
|
1180
|
-
function isWebKit() {
|
|
1181
|
-
if (isWebKitValue == null) {
|
|
1182
|
-
isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');
|
|
1183
|
-
}
|
|
1184
|
-
return isWebKitValue;
|
|
1185
|
-
}
|
|
1186
|
-
function isLastTraversableNode(node) {
|
|
1187
|
-
return /^(html|body|#document)$/.test(getNodeName(node));
|
|
1188
|
-
}
|
|
1189
|
-
function getComputedStyle(element) {
|
|
1190
|
-
return getWindow(element).getComputedStyle(element);
|
|
1191
|
-
}
|
|
1192
|
-
function getNodeScroll(element) {
|
|
1193
|
-
if (isElement(element)) {
|
|
1194
|
-
return {
|
|
1195
|
-
scrollLeft: element.scrollLeft,
|
|
1196
|
-
scrollTop: element.scrollTop
|
|
1197
|
-
};
|
|
1198
|
-
}
|
|
1199
|
-
return {
|
|
1200
|
-
scrollLeft: element.scrollX,
|
|
1201
|
-
scrollTop: element.scrollY
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
|
-
function getParentNode(node) {
|
|
1205
|
-
if (getNodeName(node) === 'html') {
|
|
1206
|
-
return node;
|
|
1207
|
-
}
|
|
1208
|
-
const result =
|
|
1209
|
-
// Step into the shadow DOM of the parent of a slotted node.
|
|
1210
|
-
node.assignedSlot ||
|
|
1211
|
-
// DOM Element detected.
|
|
1212
|
-
node.parentNode ||
|
|
1213
|
-
// ShadowRoot detected.
|
|
1214
|
-
isShadowRoot(node) && node.host ||
|
|
1215
|
-
// Fallback.
|
|
1216
|
-
getDocumentElement(node);
|
|
1217
|
-
return isShadowRoot(result) ? result.host : result;
|
|
1218
|
-
}
|
|
1219
|
-
function getNearestOverflowAncestor(node) {
|
|
1220
|
-
const parentNode = getParentNode(node);
|
|
1221
|
-
if (isLastTraversableNode(parentNode)) {
|
|
1222
|
-
return (node.ownerDocument || node).body;
|
|
1223
|
-
}
|
|
1224
|
-
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
|
|
1225
|
-
return parentNode;
|
|
1226
|
-
}
|
|
1227
|
-
return getNearestOverflowAncestor(parentNode);
|
|
1228
|
-
}
|
|
1229
|
-
function getOverflowAncestors(node, list, traverseIframes) {
|
|
1230
|
-
var _node$ownerDocument2;
|
|
1231
|
-
if (list === void 0) {
|
|
1232
|
-
list = [];
|
|
1233
|
-
}
|
|
1234
|
-
if (traverseIframes === void 0) {
|
|
1235
|
-
traverseIframes = true;
|
|
1236
|
-
}
|
|
1237
|
-
const scrollableAncestor = getNearestOverflowAncestor(node);
|
|
1238
|
-
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
|
|
1239
|
-
const win = getWindow(scrollableAncestor);
|
|
1240
|
-
if (isBody) {
|
|
1241
|
-
const frameElement = getFrameElement(win);
|
|
1242
|
-
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
|
|
1243
|
-
} else {
|
|
1244
|
-
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
function getFrameElement(win) {
|
|
1248
|
-
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
1117
|
/**
|
|
1252
1118
|
* Combines multiple cleanup functions into a single cleanup function.
|
|
1253
1119
|
*/
|
|
@@ -1277,13 +1143,15 @@ function addEventListener(target, type, listener, options) {
|
|
|
1277
1143
|
};
|
|
1278
1144
|
}
|
|
1279
1145
|
|
|
1146
|
+
const EMPTY$2 = [];
|
|
1147
|
+
|
|
1280
1148
|
/**
|
|
1281
1149
|
* A React.useEffect equivalent that runs once, when the component is mounted.
|
|
1282
1150
|
*/
|
|
1283
1151
|
function useOnMount(fn) {
|
|
1284
1152
|
// TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler -- no need to put `fn` in the dependency array
|
|
1285
1153
|
/* eslint-disable react-hooks/exhaustive-deps */
|
|
1286
|
-
React.useEffect(fn,
|
|
1154
|
+
React.useEffect(fn, EMPTY$2);
|
|
1287
1155
|
/* eslint-enable react-hooks/exhaustive-deps */
|
|
1288
1156
|
}
|
|
1289
1157
|
|
|
@@ -1347,7 +1215,7 @@ class Scheduler {
|
|
|
1347
1215
|
this.callbacksCount -= 1;
|
|
1348
1216
|
}
|
|
1349
1217
|
}
|
|
1350
|
-
|
|
1218
|
+
const scheduler = new Scheduler();
|
|
1351
1219
|
class AnimationFrame {
|
|
1352
1220
|
static create() {
|
|
1353
1221
|
return new AnimationFrame();
|
|
@@ -1787,138 +1655,6 @@ const FocusGuard = /*#__PURE__*/React.forwardRef(function FocusGuard(props, ref)
|
|
|
1787
1655
|
});
|
|
1788
1656
|
if (process.env.NODE_ENV !== "production") FocusGuard.displayName = "FocusGuard";
|
|
1789
1657
|
|
|
1790
|
-
/**
|
|
1791
|
-
* Custom positioning reference element.
|
|
1792
|
-
* @see https://floating-ui.com/docs/virtual-elements
|
|
1793
|
-
*/
|
|
1794
|
-
|
|
1795
|
-
const min = Math.min;
|
|
1796
|
-
const max = Math.max;
|
|
1797
|
-
const round = Math.round;
|
|
1798
|
-
const floor = Math.floor;
|
|
1799
|
-
const createCoords = v => ({
|
|
1800
|
-
x: v,
|
|
1801
|
-
y: v
|
|
1802
|
-
});
|
|
1803
|
-
const oppositeSideMap = {
|
|
1804
|
-
left: 'right',
|
|
1805
|
-
right: 'left',
|
|
1806
|
-
bottom: 'top',
|
|
1807
|
-
top: 'bottom'
|
|
1808
|
-
};
|
|
1809
|
-
function clamp(start, value, end) {
|
|
1810
|
-
return max(start, min(value, end));
|
|
1811
|
-
}
|
|
1812
|
-
function evaluate(value, param) {
|
|
1813
|
-
return typeof value === 'function' ? value(param) : value;
|
|
1814
|
-
}
|
|
1815
|
-
function getSide(placement) {
|
|
1816
|
-
return placement.split('-')[0];
|
|
1817
|
-
}
|
|
1818
|
-
function getAlignment(placement) {
|
|
1819
|
-
return placement.split('-')[1];
|
|
1820
|
-
}
|
|
1821
|
-
function getOppositeAxis(axis) {
|
|
1822
|
-
return axis === 'x' ? 'y' : 'x';
|
|
1823
|
-
}
|
|
1824
|
-
function getAxisLength(axis) {
|
|
1825
|
-
return axis === 'y' ? 'height' : 'width';
|
|
1826
|
-
}
|
|
1827
|
-
function getSideAxis(placement) {
|
|
1828
|
-
const firstChar = placement[0];
|
|
1829
|
-
return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';
|
|
1830
|
-
}
|
|
1831
|
-
function getAlignmentAxis(placement) {
|
|
1832
|
-
return getOppositeAxis(getSideAxis(placement));
|
|
1833
|
-
}
|
|
1834
|
-
function getAlignmentSides(placement, rects, rtl) {
|
|
1835
|
-
if (rtl === void 0) {
|
|
1836
|
-
rtl = false;
|
|
1837
|
-
}
|
|
1838
|
-
const alignment = getAlignment(placement);
|
|
1839
|
-
const alignmentAxis = getAlignmentAxis(placement);
|
|
1840
|
-
const length = getAxisLength(alignmentAxis);
|
|
1841
|
-
let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
|
|
1842
|
-
if (rects.reference[length] > rects.floating[length]) {
|
|
1843
|
-
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
|
|
1844
|
-
}
|
|
1845
|
-
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
|
|
1846
|
-
}
|
|
1847
|
-
function getExpandedPlacements(placement) {
|
|
1848
|
-
const oppositePlacement = getOppositePlacement(placement);
|
|
1849
|
-
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
|
|
1850
|
-
}
|
|
1851
|
-
function getOppositeAlignmentPlacement(placement) {
|
|
1852
|
-
return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');
|
|
1853
|
-
}
|
|
1854
|
-
const lrPlacement = ['left', 'right'];
|
|
1855
|
-
const rlPlacement = ['right', 'left'];
|
|
1856
|
-
const tbPlacement = ['top', 'bottom'];
|
|
1857
|
-
const btPlacement = ['bottom', 'top'];
|
|
1858
|
-
function getSideList(side, isStart, rtl) {
|
|
1859
|
-
switch (side) {
|
|
1860
|
-
case 'top':
|
|
1861
|
-
case 'bottom':
|
|
1862
|
-
if (rtl) return isStart ? rlPlacement : lrPlacement;
|
|
1863
|
-
return isStart ? lrPlacement : rlPlacement;
|
|
1864
|
-
case 'left':
|
|
1865
|
-
case 'right':
|
|
1866
|
-
return isStart ? tbPlacement : btPlacement;
|
|
1867
|
-
default:
|
|
1868
|
-
return [];
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
|
|
1872
|
-
const alignment = getAlignment(placement);
|
|
1873
|
-
let list = getSideList(getSide(placement), direction === 'start', rtl);
|
|
1874
|
-
if (alignment) {
|
|
1875
|
-
list = list.map(side => side + "-" + alignment);
|
|
1876
|
-
if (flipAlignment) {
|
|
1877
|
-
list = list.concat(list.map(getOppositeAlignmentPlacement));
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
return list;
|
|
1881
|
-
}
|
|
1882
|
-
function getOppositePlacement(placement) {
|
|
1883
|
-
const side = getSide(placement);
|
|
1884
|
-
return oppositeSideMap[side] + placement.slice(side.length);
|
|
1885
|
-
}
|
|
1886
|
-
function expandPaddingObject(padding) {
|
|
1887
|
-
var _padding$top, _padding$right, _padding$bottom, _padding$left;
|
|
1888
|
-
return {
|
|
1889
|
-
top: (_padding$top = padding.top) != null ? _padding$top : 0,
|
|
1890
|
-
right: (_padding$right = padding.right) != null ? _padding$right : 0,
|
|
1891
|
-
bottom: (_padding$bottom = padding.bottom) != null ? _padding$bottom : 0,
|
|
1892
|
-
left: (_padding$left = padding.left) != null ? _padding$left : 0
|
|
1893
|
-
};
|
|
1894
|
-
}
|
|
1895
|
-
function getPaddingObject(padding) {
|
|
1896
|
-
return typeof padding !== 'number' ? expandPaddingObject(padding) : {
|
|
1897
|
-
top: padding,
|
|
1898
|
-
right: padding,
|
|
1899
|
-
bottom: padding,
|
|
1900
|
-
left: padding
|
|
1901
|
-
};
|
|
1902
|
-
}
|
|
1903
|
-
function rectToClientRect(rect) {
|
|
1904
|
-
const {
|
|
1905
|
-
x,
|
|
1906
|
-
y,
|
|
1907
|
-
width,
|
|
1908
|
-
height
|
|
1909
|
-
} = rect;
|
|
1910
|
-
return {
|
|
1911
|
-
width,
|
|
1912
|
-
height,
|
|
1913
|
-
top: y,
|
|
1914
|
-
left: x,
|
|
1915
|
-
right: x + width,
|
|
1916
|
-
bottom: y + height,
|
|
1917
|
-
x,
|
|
1918
|
-
y
|
|
1919
|
-
};
|
|
1920
|
-
}
|
|
1921
|
-
|
|
1922
1658
|
function isDifferentGridRow(index, cols, prevRow) {
|
|
1923
1659
|
return Math.floor(index / cols) !== prevRow;
|
|
1924
1660
|
}
|
|
@@ -2214,13 +1950,6 @@ function isListIndexDisabled(list, index, disabledIndices) {
|
|
|
2214
1950
|
if (!isElementVisible(element)) {
|
|
2215
1951
|
return true;
|
|
2216
1952
|
}
|
|
2217
|
-
|
|
2218
|
-
// A natively disabled element can never receive focus, so it must always be
|
|
2219
|
-
// skipped, even when `disabledIndices` marks it as enabled. Only
|
|
2220
|
-
// `aria-disabled` items can be focusable-while-disabled.
|
|
2221
|
-
if (element.matches(':disabled')) {
|
|
2222
|
-
return true;
|
|
2223
|
-
}
|
|
2224
1953
|
return !disabledIndices && (element.hasAttribute('disabled') || element.getAttribute('aria-disabled') === 'true');
|
|
2225
1954
|
}
|
|
2226
1955
|
function isHiddenByStyles(styles) {
|
|
@@ -2751,6 +2480,11 @@ function useFloatingPortalNode(props = {}) {
|
|
|
2751
2480
|
}
|
|
2752
2481
|
return;
|
|
2753
2482
|
}
|
|
2483
|
+
|
|
2484
|
+
// React 17 does not use React.useId().
|
|
2485
|
+
if (uniqueId == null) {
|
|
2486
|
+
return;
|
|
2487
|
+
}
|
|
2754
2488
|
const resolvedContainer = (containerProp && (isNode(containerProp) ? containerProp : containerProp.current)) ?? parentPortalNode ?? document.body;
|
|
2755
2489
|
if (resolvedContainer == null) {
|
|
2756
2490
|
if (containerRef.current) {
|
|
@@ -2765,7 +2499,7 @@ function useFloatingPortalNode(props = {}) {
|
|
|
2765
2499
|
setPortalNode(null);
|
|
2766
2500
|
setContainerElement(resolvedContainer);
|
|
2767
2501
|
}
|
|
2768
|
-
}, [containerProp, parentPortalNode]);
|
|
2502
|
+
}, [containerProp, parentPortalNode, uniqueId]);
|
|
2769
2503
|
const portalElement = useRenderElement('div', componentProps, {
|
|
2770
2504
|
ref: [ref, setPortalNodeRef],
|
|
2771
2505
|
props: [{
|
|
@@ -2778,11 +2512,8 @@ function useFloatingPortalNode(props = {}) {
|
|
|
2778
2512
|
// Another call inside `FloatingPortal`/`FloatingPortalLite` then injects the children into `portalElement`.
|
|
2779
2513
|
const portalSubtree = containerElement && portalElement ? /*#__PURE__*/ReactDOM.createPortal(portalElement, containerElement) : null;
|
|
2780
2514
|
return {
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
// rendered value so `aria-owns` never points at an ID absent from the DOM.
|
|
2784
|
-
nodeId: /*#__PURE__*/React.isValidElement(portalElement) ? portalElement.props.id : undefined,
|
|
2785
|
-
subtree: portalSubtree
|
|
2515
|
+
portalNode,
|
|
2516
|
+
portalSubtree
|
|
2786
2517
|
};
|
|
2787
2518
|
}
|
|
2788
2519
|
|
|
@@ -2802,12 +2533,12 @@ const FloatingPortal = /*#__PURE__*/React.forwardRef(function FloatingPortal(com
|
|
|
2802
2533
|
style,
|
|
2803
2534
|
children,
|
|
2804
2535
|
container,
|
|
2536
|
+
renderGuards,
|
|
2805
2537
|
...elementProps
|
|
2806
2538
|
} = componentProps;
|
|
2807
2539
|
const {
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
subtree: portalSubtree
|
|
2540
|
+
portalNode,
|
|
2541
|
+
portalSubtree
|
|
2811
2542
|
} = useFloatingPortalNode({
|
|
2812
2543
|
container,
|
|
2813
2544
|
ref: forwardedRef,
|
|
@@ -2822,7 +2553,7 @@ const FloatingPortal = /*#__PURE__*/React.forwardRef(function FloatingPortal(com
|
|
|
2822
2553
|
const focusInsideDisabledRef = React.useRef(false);
|
|
2823
2554
|
const modal = focusManagerState?.modal;
|
|
2824
2555
|
const open = focusManagerState?.open;
|
|
2825
|
-
const shouldRenderGuards = !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode;
|
|
2556
|
+
const shouldRenderGuards = typeof renderGuards === 'boolean' ? renderGuards : !!focusManagerState && !focusManagerState.modal && focusManagerState.open && !!portalNode;
|
|
2826
2557
|
|
|
2827
2558
|
// https://codesandbox.io/s/tabbable-portal-f4tng?file=/src/TabbablePortal.tsx
|
|
2828
2559
|
React.useEffect(() => {
|
|
@@ -2884,7 +2615,7 @@ const FloatingPortal = /*#__PURE__*/React.forwardRef(function FloatingPortal(com
|
|
|
2884
2615
|
}
|
|
2885
2616
|
}
|
|
2886
2617
|
}), shouldRenderGuards && portalNode && /*#__PURE__*/jsx("span", {
|
|
2887
|
-
"aria-owns":
|
|
2618
|
+
"aria-owns": portalNode.id,
|
|
2888
2619
|
style: ownerVisuallyHidden
|
|
2889
2620
|
}), portalNode && /*#__PURE__*/ReactDOM.createPortal(children, portalNode), shouldRenderGuards && portalNode && /*#__PURE__*/jsx(FocusGuard, {
|
|
2890
2621
|
"data-type": "outside",
|
|
@@ -3148,10 +2879,11 @@ function FloatingFocusManager(props) {
|
|
|
3148
2879
|
} = store.context;
|
|
3149
2880
|
const getNodeId = useStableCallback(() => dataRef.current.floatingContext?.nodeId);
|
|
3150
2881
|
const ignoreInitialFocus = initialFocus === false;
|
|
3151
|
-
//
|
|
3152
|
-
//
|
|
3153
|
-
//
|
|
3154
|
-
//
|
|
2882
|
+
// If the reference is a combobox and is typeable (e.g. input/textarea),
|
|
2883
|
+
// there are different focus semantics. The guards should not be rendered, but
|
|
2884
|
+
// aria-hidden should be applied to all nodes still. Further, the visually
|
|
2885
|
+
// hidden dismiss button should only appear at the end of the list, not the
|
|
2886
|
+
// start.
|
|
3155
2887
|
const isUntrappedTypeableCombobox = isTypeableCombobox(domReference) && ignoreInitialFocus;
|
|
3156
2888
|
const initialFocusRef = useValueAsRef(initialFocus);
|
|
3157
2889
|
const returnFocusRef = useValueAsRef(returnFocus);
|
|
@@ -3265,12 +2997,12 @@ function FloatingFocusManager(props) {
|
|
|
3265
2997
|
const triggers = store.context.triggerElements;
|
|
3266
2998
|
const insideElements = getResolvedInsideElements();
|
|
3267
2999
|
const isRelatedFocusGuard = relatedTarget?.hasAttribute(createAttribute('focus-guard')) && [beforeGuardRef.current, afterGuardRef.current, portalContext?.beforeInsideRef.current, portalContext?.afterInsideRef.current, portalContext?.beforeOutsideRef.current, portalContext?.afterOutsideRef.current, resolveRef(previousFocusableElement), resolveRef(nextFocusableElement)].includes(relatedTarget);
|
|
3268
|
-
const movedToUnrelatedNode = !(contains(domReference, relatedTarget) || contains(floating, relatedTarget) || contains(relatedTarget, floating) || contains(portalContext?.portalNode, relatedTarget) || insideElements.some(element => element === relatedTarget || contains(element, relatedTarget)) || triggers.hasMatchingElement(trigger => contains(trigger, relatedTarget)) || isRelatedFocusGuard || tree && (getNodeChildren(tree.nodesRef.current, nodeId).find(node => contains(node.context?.elements.floating, relatedTarget) || contains(node.context?.elements.domReference, relatedTarget)) || getNodeAncestors(tree.nodesRef.current, nodeId).find(node => [node.context?.elements.floating, getFloatingFocusElement(node.context?.elements.floating)].includes(relatedTarget) || node.context?.elements.domReference === relatedTarget)));
|
|
3000
|
+
const movedToUnrelatedNode = !(contains(domReference, relatedTarget) || contains(floating, relatedTarget) || contains(relatedTarget, floating) || contains(portalContext?.portalNode, relatedTarget) || insideElements.some(element => element === relatedTarget || contains(element, relatedTarget)) || relatedTarget != null && triggers.hasElement(relatedTarget) || triggers.hasMatchingElement(trigger => contains(trigger, relatedTarget)) || isRelatedFocusGuard || tree && (getNodeChildren(tree.nodesRef.current, nodeId).find(node => contains(node.context?.elements.floating, relatedTarget) || contains(node.context?.elements.domReference, relatedTarget)) || getNodeAncestors(tree.nodesRef.current, nodeId).find(node => [node.context?.elements.floating, getFloatingFocusElement(node.context?.elements.floating)].includes(relatedTarget) || node.context?.elements.domReference === relatedTarget)));
|
|
3269
3001
|
if (currentTarget === domReference && floatingFocusElement) {
|
|
3270
3002
|
handleTabIndex(floatingFocusElement);
|
|
3271
3003
|
}
|
|
3272
3004
|
|
|
3273
|
-
// Restore focus to the
|
|
3005
|
+
// Restore focus to the previous tabbable element index to prevent
|
|
3274
3006
|
// focus from being lost outside the floating tree.
|
|
3275
3007
|
if (restoreFocus && currentTarget !== domReference && !isElementVisible(target) && activeElement(doc) === doc.body) {
|
|
3276
3008
|
// Let `FloatingPortal` effect knows that focus is still inside the
|
|
@@ -3280,10 +3012,10 @@ function FloatingFocusManager(props) {
|
|
|
3280
3012
|
// If explicitly requested to restore focus to the popup container, do not search
|
|
3281
3013
|
// for the next/previous tabbable element.
|
|
3282
3014
|
if (restoreFocus === 'popup') {
|
|
3283
|
-
// If the
|
|
3284
|
-
//
|
|
3285
|
-
//
|
|
3286
|
-
//
|
|
3015
|
+
// If the element is removed on pointerdown, focus tries to move it,
|
|
3016
|
+
// but since it's removed at the same time, focus gets lost as it
|
|
3017
|
+
// happens after the .focus() call above.
|
|
3018
|
+
// In this case, focus needs to be moved asynchronously.
|
|
3287
3019
|
restoreFocusFrame.request(() => {
|
|
3288
3020
|
floatingFocusElement.focus();
|
|
3289
3021
|
});
|
|
@@ -3365,8 +3097,6 @@ function FloatingFocusManager(props) {
|
|
|
3365
3097
|
if (!open || disabled || !isHTMLElement(floatingFocusElement)) {
|
|
3366
3098
|
return;
|
|
3367
3099
|
}
|
|
3368
|
-
closeTypeRef.current = '';
|
|
3369
|
-
lastInteractionTypeRef.current = '';
|
|
3370
3100
|
const doc = ownerDocument(floatingFocusElement);
|
|
3371
3101
|
const previouslyFocusedElement = activeElement(doc);
|
|
3372
3102
|
|
|
@@ -3398,9 +3128,7 @@ function FloatingFocusManager(props) {
|
|
|
3398
3128
|
}
|
|
3399
3129
|
elToFocus = elToFocus || getDefaultFocusElement();
|
|
3400
3130
|
const hadFocusInside = contains(floatingFocusElement, activeElement(doc));
|
|
3401
|
-
|
|
3402
|
-
// enqueueFocus returns a rAF-cancel function; we intentionally don't cancel this focus.
|
|
3403
|
-
void enqueueFocus(elToFocus, {
|
|
3131
|
+
enqueueFocus(elToFocus, {
|
|
3404
3132
|
preventScroll: elToFocus === floatingFocusElement,
|
|
3405
3133
|
shouldFocus() {
|
|
3406
3134
|
// This focus is queued on the next animation frame. If the floating element has closed
|
|
@@ -3427,11 +3155,13 @@ function FloatingFocusManager(props) {
|
|
|
3427
3155
|
}
|
|
3428
3156
|
const doc = ownerDocument(floatingFocusElement);
|
|
3429
3157
|
const elementFocusedBeforeOpen = activeElement(doc);
|
|
3430
|
-
// Only
|
|
3431
|
-
//
|
|
3432
|
-
// here as nullish and is intentionally not treated as programmatic.
|
|
3158
|
+
// Only nullish interaction types represent programmatic opens. The empty
|
|
3159
|
+
// string default is intentionally not treated as programmatic.
|
|
3433
3160
|
const preferPreviousFocus = openInteractionTypeRef.current == null;
|
|
3434
3161
|
addPreviouslyFocusedElement(elementFocusedBeforeOpen);
|
|
3162
|
+
|
|
3163
|
+
// Dismissing via outside press should always ignore `returnFocus` to
|
|
3164
|
+
// prevent unwanted scrolling.
|
|
3435
3165
|
function onOpenChangeLocal(details) {
|
|
3436
3166
|
if (!details.open) {
|
|
3437
3167
|
closeTypeRef.current = getEventType(details.nativeEvent, lastInteractionTypeRef.current);
|
|
@@ -3447,11 +3177,6 @@ function FloatingFocusManager(props) {
|
|
|
3447
3177
|
} else if (isVirtualClick(details.nativeEvent) || isVirtualPointerEvent(details.nativeEvent)) {
|
|
3448
3178
|
preventReturnFocusRef.current = false;
|
|
3449
3179
|
} else {
|
|
3450
|
-
// On outside press, only return focus to the reference when the browser supports the
|
|
3451
|
-
// `focus({ preventScroll })` option; without it, restoring focus scrolls the page.
|
|
3452
|
-
// Chrome on Android and Samsung Internet still don't support `preventScroll`
|
|
3453
|
-
// (https://issues.chromium.org/issues/41453122), so the runtime check keeps return
|
|
3454
|
-
// focus disabled there to avoid the scroll jump.
|
|
3455
3180
|
let isPreventScrollSupported = false;
|
|
3456
3181
|
ownerDocument(floatingFocusElement).createElement('div').focus({
|
|
3457
3182
|
get preventScroll() {
|
|
@@ -3467,9 +3192,9 @@ function FloatingFocusManager(props) {
|
|
|
3467
3192
|
}
|
|
3468
3193
|
}
|
|
3469
3194
|
events.on('openchange', onOpenChangeLocal);
|
|
3470
|
-
function getReturnElement(
|
|
3195
|
+
function getReturnElement() {
|
|
3471
3196
|
const returnFocusValueOrFn = returnFocusRef.current;
|
|
3472
|
-
let resolvedReturnFocusValue = typeof returnFocusValueOrFn === 'function' ? returnFocusValueOrFn(
|
|
3197
|
+
let resolvedReturnFocusValue = typeof returnFocusValueOrFn === 'function' ? returnFocusValueOrFn(closeTypeRef.current) : returnFocusValueOrFn;
|
|
3473
3198
|
|
|
3474
3199
|
// `null` should fallback to default behavior in case of an empty ref.
|
|
3475
3200
|
if (resolvedReturnFocusValue === undefined || resolvedReturnFocusValue === false) {
|
|
@@ -3497,11 +3222,9 @@ function FloatingFocusManager(props) {
|
|
|
3497
3222
|
|
|
3498
3223
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3499
3224
|
const returnFocusValueOrFn = returnFocusRef.current;
|
|
3500
|
-
const
|
|
3501
|
-
const returnElement = getReturnElement(closeType);
|
|
3225
|
+
const returnElement = getReturnElement();
|
|
3502
3226
|
queueMicrotask(() => {
|
|
3503
|
-
// `returnElement
|
|
3504
|
-
// otherwise `returnElement` itself (which may not be tabbable at all).
|
|
3227
|
+
// This is `returnElement`, if it's tabbable, or its first tabbable child.
|
|
3505
3228
|
const tabbableReturnElement = getFirstTabbableElement(returnElement);
|
|
3506
3229
|
const hasExplicitReturnFocus = typeof returnFocusValueOrFn !== 'boolean';
|
|
3507
3230
|
if (returnFocusValueOrFn && !preventReturnFocusRef.current && isHTMLElement(tabbableReturnElement) && (
|
|
@@ -3509,13 +3232,9 @@ function FloatingFocusManager(props) {
|
|
|
3509
3232
|
// since it likely entered a different element which should be
|
|
3510
3233
|
// respected: https://github.com/floating-ui/floating-ui/issues/2607
|
|
3511
3234
|
!hasExplicitReturnFocus && tabbableReturnElement !== activeEl && activeEl !== doc.body ? isFocusInsideFloatingTree : true)) {
|
|
3512
|
-
|
|
3235
|
+
tabbableReturnElement.focus({
|
|
3513
3236
|
preventScroll: true
|
|
3514
|
-
};
|
|
3515
|
-
if (closeType === 'keyboard') {
|
|
3516
|
-
focusOptions.focusVisible = true;
|
|
3517
|
-
}
|
|
3518
|
-
tabbableReturnElement.focus(focusOptions);
|
|
3237
|
+
});
|
|
3519
3238
|
}
|
|
3520
3239
|
preventReturnFocusRef.current = false;
|
|
3521
3240
|
});
|
|
@@ -3538,8 +3257,8 @@ function FloatingFocusManager(props) {
|
|
|
3538
3257
|
}
|
|
3539
3258
|
}, [open, floating]);
|
|
3540
3259
|
|
|
3541
|
-
// Synchronize the
|
|
3542
|
-
//
|
|
3260
|
+
// Synchronize the `context` & `modal` value to the FloatingPortal context.
|
|
3261
|
+
// It will decide whether or not it needs to render its own guards.
|
|
3543
3262
|
useIsoLayoutEffect(() => {
|
|
3544
3263
|
if (disabled || !portalContext) {
|
|
3545
3264
|
return undefined;
|
|
@@ -3574,8 +3293,7 @@ function FloatingFocusManager(props) {
|
|
|
3574
3293
|
onFocus: event => {
|
|
3575
3294
|
if (modal) {
|
|
3576
3295
|
const els = getTabbableContent();
|
|
3577
|
-
|
|
3578
|
-
void enqueueFocus(els[els.length - 1]);
|
|
3296
|
+
enqueueFocus(els[els.length - 1]);
|
|
3579
3297
|
} else if (portalContext?.portalNode) {
|
|
3580
3298
|
preventReturnFocusRef.current = false;
|
|
3581
3299
|
if (isOutsideEvent(event, portalContext.portalNode)) {
|
|
@@ -3591,8 +3309,7 @@ function FloatingFocusManager(props) {
|
|
|
3591
3309
|
ref: mergedAfterGuardRef,
|
|
3592
3310
|
onFocus: event => {
|
|
3593
3311
|
if (modal) {
|
|
3594
|
-
|
|
3595
|
-
void enqueueFocus(getTabbableContent()[0]);
|
|
3312
|
+
enqueueFocus(getTabbableContent()[0]);
|
|
3596
3313
|
} else if (portalContext?.portalNode) {
|
|
3597
3314
|
if (closeOnFocusOut) {
|
|
3598
3315
|
preventReturnFocusRef.current = true;
|
|
@@ -3664,11 +3381,7 @@ function useClick(context, props = {}) {
|
|
|
3664
3381
|
}
|
|
3665
3382
|
return {
|
|
3666
3383
|
onPointerDown(event) {
|
|
3667
|
-
|
|
3668
|
-
// mouse-like `pointerType`, but `ignoreMouse` must not drop them: hover logic cannot
|
|
3669
|
-
// open for a virtual press since there is no real pointer movement to wait for.
|
|
3670
|
-
// Virtual `touch` presses (iOS VoiceOver) keep their type so `touchOpenDelay` applies.
|
|
3671
|
-
pointerTypeRef.current = isMouseLikePointerType(event.pointerType, true) && isVirtualPointerEvent(event.nativeEvent) ? 'virtual' : event.pointerType;
|
|
3384
|
+
pointerTypeRef.current = event.pointerType;
|
|
3672
3385
|
},
|
|
3673
3386
|
onMouseDown(event) {
|
|
3674
3387
|
const pointerType = pointerTypeRef.current;
|
|
@@ -3848,7 +3561,7 @@ function useDismiss(context, props = {}) {
|
|
|
3848
3561
|
});
|
|
3849
3562
|
React.useEffect(() => {
|
|
3850
3563
|
if (!open || !enabled) {
|
|
3851
|
-
return
|
|
3564
|
+
return undefined;
|
|
3852
3565
|
}
|
|
3853
3566
|
dataRef.current.__escapeKeyBubbles = escapeKeyBubbles;
|
|
3854
3567
|
dataRef.current.__outsidePressBubbles = outsidePressBubbles;
|
|
@@ -4126,9 +3839,9 @@ function useDismiss(context, props = {}) {
|
|
|
4126
3839
|
preventedPressSuppressionTimeout.clear();
|
|
4127
3840
|
resetPressStartState();
|
|
4128
3841
|
suppressNextOutsideClickRef.current = false;
|
|
4129
|
-
clearInsideReactTree();
|
|
4130
3842
|
};
|
|
4131
3843
|
}, [dataRef, floatingElement, escapeKey$1, outsidePressEnabled, outsidePress$1, open, enabled, escapeKeyBubbles, outsidePressBubbles, closeOnEscapeKeyDown, clearInsideReactTree, getOutsidePressEventProp, hasBlockingChild, isEventWithinOwnElements, tree, store, cancelDismissOnEndTimeout]);
|
|
3844
|
+
React.useEffect(clearInsideReactTree, [outsidePress$1, clearInsideReactTree]);
|
|
4132
3845
|
const reference = React.useMemo(() => ({
|
|
4133
3846
|
onKeyDown: closeOnEscapeKeyDown,
|
|
4134
3847
|
onPointerDown: closeOnReferencePress,
|
|
@@ -4162,12 +3875,12 @@ function useDismiss(context, props = {}) {
|
|
|
4162
3875
|
}
|
|
4163
3876
|
|
|
4164
3877
|
const selectors = {
|
|
4165
|
-
open: state => state.open,
|
|
4166
|
-
transitionStatus: state => state.transitionStatus,
|
|
4167
|
-
domReferenceElement: state => state.domReferenceElement,
|
|
4168
|
-
referenceElement: state => state.positionReference ?? state.referenceElement,
|
|
4169
|
-
floatingElement: state => state.floatingElement,
|
|
4170
|
-
floatingId: state => state.floatingId
|
|
3878
|
+
open: createSelector(state => state.open),
|
|
3879
|
+
transitionStatus: createSelector(state => state.transitionStatus),
|
|
3880
|
+
domReferenceElement: createSelector(state => state.domReferenceElement),
|
|
3881
|
+
referenceElement: createSelector(state => state.positionReference ?? state.referenceElement),
|
|
3882
|
+
floatingElement: createSelector(state => state.floatingElement),
|
|
3883
|
+
floatingId: createSelector(state => state.floatingId)
|
|
4171
3884
|
};
|
|
4172
3885
|
class FloatingRootStore extends ReactStore {
|
|
4173
3886
|
constructor(options) {
|
|
@@ -4356,14 +4069,44 @@ function useTransitionStatus(open, enableIdleState = false, deferEndingState = f
|
|
|
4356
4069
|
};
|
|
4357
4070
|
}
|
|
4358
4071
|
|
|
4072
|
+
let TransitionStatusDataAttributes = /*#__PURE__*/function (TransitionStatusDataAttributes) {
|
|
4073
|
+
/**
|
|
4074
|
+
* Present when the component is animating in.
|
|
4075
|
+
*/
|
|
4076
|
+
TransitionStatusDataAttributes["startingStyle"] = "data-starting-style";
|
|
4077
|
+
/**
|
|
4078
|
+
* Present when the component is animating out.
|
|
4079
|
+
*/
|
|
4080
|
+
TransitionStatusDataAttributes["endingStyle"] = "data-ending-style";
|
|
4081
|
+
return TransitionStatusDataAttributes;
|
|
4082
|
+
}({});
|
|
4083
|
+
const STARTING_HOOK = {
|
|
4084
|
+
[TransitionStatusDataAttributes.startingStyle]: ''
|
|
4085
|
+
};
|
|
4086
|
+
const ENDING_HOOK = {
|
|
4087
|
+
[TransitionStatusDataAttributes.endingStyle]: ''
|
|
4088
|
+
};
|
|
4089
|
+
const transitionStatusMapping = {
|
|
4090
|
+
transitionStatus(value) {
|
|
4091
|
+
if (value === 'starting') {
|
|
4092
|
+
return STARTING_HOOK;
|
|
4093
|
+
}
|
|
4094
|
+
if (value === 'ending') {
|
|
4095
|
+
return ENDING_HOOK;
|
|
4096
|
+
}
|
|
4097
|
+
return null;
|
|
4098
|
+
}
|
|
4099
|
+
};
|
|
4100
|
+
|
|
4359
4101
|
/**
|
|
4360
4102
|
* Executes a function once all animations have finished on the provided element.
|
|
4361
|
-
* If an animation is canceled, waits for any replacement animations before executing.
|
|
4362
4103
|
* @param elementOrRef - The element to watch for animations.
|
|
4363
4104
|
* @param waitForStartingStyleRemoved - Whether to wait for [data-starting-style] to be removed before checking for animations.
|
|
4105
|
+
* @param treatAbortedAsFinished - Whether to treat aborted animations as finished. If `false`, and there are aborted animations,
|
|
4106
|
+
* the function will check again if any new animations have started and wait for them to finish.
|
|
4364
4107
|
* @returns A function that takes a callback to execute once all animations have finished, and an optional AbortSignal to abort the callback
|
|
4365
4108
|
*/
|
|
4366
|
-
function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false) {
|
|
4109
|
+
function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false, treatAbortedAsFinished = true) {
|
|
4367
4110
|
const frame = useAnimationFrame();
|
|
4368
4111
|
return useStableCallback((fnToExecute,
|
|
4369
4112
|
/**
|
|
@@ -4392,22 +4135,23 @@ function useAnimationsFinished(elementOrRef, waitForStartingStyleRemoved = false
|
|
|
4392
4135
|
if (!signal?.aborted) {
|
|
4393
4136
|
done();
|
|
4394
4137
|
}
|
|
4395
|
-
}
|
|
4396
|
-
if (
|
|
4138
|
+
}).catch(() => {
|
|
4139
|
+
if (treatAbortedAsFinished) {
|
|
4140
|
+
if (!signal?.aborted) {
|
|
4141
|
+
done();
|
|
4142
|
+
}
|
|
4397
4143
|
return;
|
|
4398
4144
|
}
|
|
4399
4145
|
const currentAnimations = resolvedElement.getAnimations();
|
|
4400
|
-
if (currentAnimations.some(animation => animation.pending || animation.playState !== 'finished')) {
|
|
4146
|
+
if (!signal?.aborted && currentAnimations.length > 0 && currentAnimations.some(animation => animation.pending || animation.playState !== 'finished')) {
|
|
4401
4147
|
// Sometimes animations can be aborted because a property they depend on changes while the animation plays.
|
|
4402
4148
|
// In such cases, we need to re-check if any new animations have started.
|
|
4403
4149
|
exec();
|
|
4404
|
-
return;
|
|
4405
4150
|
}
|
|
4406
|
-
done();
|
|
4407
4151
|
});
|
|
4408
4152
|
}
|
|
4409
4153
|
if (waitForStartingStyleRemoved) {
|
|
4410
|
-
const startingStyleAttribute =
|
|
4154
|
+
const startingStyleAttribute = TransitionStatusDataAttributes.startingStyle;
|
|
4411
4155
|
|
|
4412
4156
|
// If `[data-starting-style]` isn't present, fall back to waiting one more frame
|
|
4413
4157
|
// to give "open" animations a chance to be registered.
|
|
@@ -4447,7 +4191,7 @@ function useOpenChangeComplete(parameters) {
|
|
|
4447
4191
|
onComplete: onCompleteParam
|
|
4448
4192
|
} = parameters;
|
|
4449
4193
|
const onComplete = useStableCallback(onCompleteParam);
|
|
4450
|
-
const runOnceAnimationsFinish = useAnimationsFinished(ref, open);
|
|
4194
|
+
const runOnceAnimationsFinish = useAnimationsFinished(ref, open, false);
|
|
4451
4195
|
React.useEffect(() => {
|
|
4452
4196
|
if (!enabled) {
|
|
4453
4197
|
return undefined;
|
|
@@ -4473,26 +4217,14 @@ const FOCUSABLE_POPUP_PROPS = {
|
|
|
4473
4217
|
function createDefaultInitialFocus(popupRef) {
|
|
4474
4218
|
return interactionType => interactionType === 'touch' ? popupRef.current : true;
|
|
4475
4219
|
}
|
|
4476
|
-
|
|
4477
|
-
/**
|
|
4478
|
-
* The subset of a popup handle that a Root needs to bind its store to. Both the real handle classes
|
|
4479
|
-
* and any test double satisfy it.
|
|
4480
|
-
*/
|
|
4481
|
-
|
|
4482
|
-
/**
|
|
4483
|
-
* Creates and owns a popup store on behalf of a Root part. The store is created exactly once, with
|
|
4484
|
-
* controlled props and root state synced separately after creation. Sets up the synced floating
|
|
4485
|
-
* root context and returns the store.
|
|
4486
|
-
*
|
|
4487
|
-
* @param createStore Factory that builds the store. Called exactly once, receiving the floating id
|
|
4488
|
-
* and whether the popup is nested inside another floating element, both resolved on the first render.
|
|
4489
|
-
* @param treatPopupAsFloatingElement Whether the popup element is passed to Floating UI as the
|
|
4490
|
-
* floating element instead of the default positioner.
|
|
4491
|
-
*/
|
|
4492
|
-
function usePopupRootStore(createStore, treatPopupAsFloatingElement = false) {
|
|
4220
|
+
function usePopupStore(externalStore, createStore, treatPopupAsFloatingElement = false) {
|
|
4493
4221
|
const floatingId = useId();
|
|
4494
4222
|
const nested = useFloatingParentNodeId() != null;
|
|
4495
|
-
const
|
|
4223
|
+
const internalStoreRef = React.useRef(null);
|
|
4224
|
+
if (externalStore === undefined && internalStoreRef.current === null) {
|
|
4225
|
+
internalStoreRef.current = createStore(floatingId, nested);
|
|
4226
|
+
}
|
|
4227
|
+
const store = externalStore ?? internalStoreRef.current;
|
|
4496
4228
|
useSyncedFloatingRootContext({
|
|
4497
4229
|
popupStore: store,
|
|
4498
4230
|
treatPopupAsFloatingElement,
|
|
@@ -4501,27 +4233,10 @@ function usePopupRootStore(createStore, treatPopupAsFloatingElement = false) {
|
|
|
4501
4233
|
nested,
|
|
4502
4234
|
onOpenChange: store.setOpen
|
|
4503
4235
|
});
|
|
4504
|
-
return
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
* Attaches a Root's store to a handle for this component's committed lifetime. Popup Roots render
|
|
4509
|
-
* it before their interactions and user children so its layout effect runs before descendant layout
|
|
4510
|
-
* effects. This lets descendants call the handle during the Root's initial commit without attaching
|
|
4511
|
-
* during render, which would leak suspended or abandoned stores. Store subscribers are notified by
|
|
4512
|
-
* `attachStore` in this ordinary layout phase, where React permits synchronous updates.
|
|
4513
|
-
*
|
|
4514
|
-
* Popup Roots must render this component only when a handle is present so handle-less Roots avoid
|
|
4515
|
-
* mounting an extra fiber and layout effect.
|
|
4516
|
-
*/
|
|
4517
|
-
function PopupHandleAttachment({
|
|
4518
|
-
handle,
|
|
4519
|
-
store
|
|
4520
|
-
}) {
|
|
4521
|
-
useIsoLayoutEffect(() => {
|
|
4522
|
-
return handle.attachStore(store);
|
|
4523
|
-
}, [handle, store]);
|
|
4524
|
-
return null;
|
|
4236
|
+
return {
|
|
4237
|
+
store,
|
|
4238
|
+
internalStore: internalStoreRef.current
|
|
4239
|
+
};
|
|
4525
4240
|
}
|
|
4526
4241
|
|
|
4527
4242
|
/**
|
|
@@ -4586,6 +4301,19 @@ function attachPreventUnmountOnClose(eventDetails) {
|
|
|
4586
4301
|
};
|
|
4587
4302
|
return () => preventUnmountOnClose;
|
|
4588
4303
|
}
|
|
4304
|
+
function useInitialOpenSync(store, openProp, defaultOpen, defaultTriggerId) {
|
|
4305
|
+
useOnFirstRender(() => {
|
|
4306
|
+
if (openProp === undefined && store.state.open === false && defaultOpen) {
|
|
4307
|
+
// Avoid notifying detached trigger subscribers while the Root is rendering.
|
|
4308
|
+
store.state = {
|
|
4309
|
+
...store.state,
|
|
4310
|
+
open: true,
|
|
4311
|
+
activeTriggerId: defaultTriggerId,
|
|
4312
|
+
preventUnmountingOnClose: false
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
});
|
|
4316
|
+
}
|
|
4589
4317
|
|
|
4590
4318
|
/**
|
|
4591
4319
|
* Sets up trigger data forwarding to the store.
|
|
@@ -4598,11 +4326,11 @@ function attachPreventUnmountOnClose(eventDetails) {
|
|
|
4598
4326
|
function useTriggerDataForwarding(triggerId, triggerElementRef, store, stateUpdates) {
|
|
4599
4327
|
const isMountedByThisTrigger = store.useState('isMountedByTrigger', triggerId);
|
|
4600
4328
|
const baseRegisterTrigger = useTriggerRegistration(triggerId, store);
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4329
|
+
const registerTrigger = useStableCallback(element => {
|
|
4330
|
+
baseRegisterTrigger(element);
|
|
4331
|
+
if (!element) {
|
|
4332
|
+
return;
|
|
4333
|
+
}
|
|
4606
4334
|
const open = store.select('open');
|
|
4607
4335
|
const activeTriggerId = store.select('activeTriggerId');
|
|
4608
4336
|
if (activeTriggerId === triggerId) {
|
|
@@ -4623,18 +4351,6 @@ function useTriggerDataForwarding(triggerId, triggerElementRef, store, stateUpda
|
|
|
4623
4351
|
});
|
|
4624
4352
|
}
|
|
4625
4353
|
});
|
|
4626
|
-
|
|
4627
|
-
// Intentionally NOT stable. Its identity is derived from `baseRegisterTrigger`, which is keyed on
|
|
4628
|
-
// `[store, id]`, so when a handle-backed trigger's store pointer swaps the merged ref re-fires —
|
|
4629
|
-
// unregistering from the previous store and registering into the new one. This lets a detached
|
|
4630
|
-
// trigger follow its handle's currently-attached store across attach/detach/remount. (A stable
|
|
4631
|
-
// callback would keep its identity and never re-fire on a store swap.)
|
|
4632
|
-
const registerTrigger = React.useCallback(element => {
|
|
4633
|
-
baseRegisterTrigger(element);
|
|
4634
|
-
if (element) {
|
|
4635
|
-
applyTriggerData(element);
|
|
4636
|
-
}
|
|
4637
|
-
}, [baseRegisterTrigger, applyTriggerData]);
|
|
4638
4354
|
useIsoLayoutEffect(() => {
|
|
4639
4355
|
if (isMountedByThisTrigger) {
|
|
4640
4356
|
store.update({
|
|
@@ -4654,17 +4370,12 @@ function useTriggerDataForwarding(triggerId, triggerElementRef, store, stateUpda
|
|
|
4654
4370
|
*
|
|
4655
4371
|
* When a popup opens without an explicit trigger id and exactly one trigger is registered, that
|
|
4656
4372
|
* trigger is claimed as the active trigger. When the active trigger id is still registered but its
|
|
4657
|
-
* element changed, the active element is refreshed. When the active trigger
|
|
4658
|
-
*
|
|
4659
|
-
*
|
|
4660
|
-
* reassociated to the registered id instead of being treated as lost. When the active trigger
|
|
4661
|
-
* unregisters, the default path preserves existing ownership so non-closing popup families do not
|
|
4662
|
-
* silently claim a different trigger while staying open.
|
|
4373
|
+
* element changed, the active element is refreshed. When the active trigger unregisters, the
|
|
4374
|
+
* default path preserves existing ownership so non-closing popup families do not silently claim a
|
|
4375
|
+
* different trigger while staying open.
|
|
4663
4376
|
*
|
|
4664
|
-
* If `closeOnActiveTriggerUnmount` is enabled, unregistering
|
|
4665
|
-
*
|
|
4666
|
-
* register first. An active trigger id that has not matched a registered trigger yet is treated as
|
|
4667
|
-
* pending and does not request a close.
|
|
4377
|
+
* If `closeOnActiveTriggerUnmount` is enabled, unregistering the active trigger requests a close
|
|
4378
|
+
* after a microtask so a same-tick replacement trigger with the same id can register first.
|
|
4668
4379
|
*
|
|
4669
4380
|
* This should be called on the Root part.
|
|
4670
4381
|
*
|
|
@@ -4675,22 +4386,10 @@ function useImplicitActiveTrigger(store, options = {}) {
|
|
|
4675
4386
|
const {
|
|
4676
4387
|
closeOnActiveTriggerUnmount = false
|
|
4677
4388
|
} = options;
|
|
4678
|
-
// Distinguishes a trigger that unmounted from a new active trigger that has not hydrated yet.
|
|
4679
|
-
const resolvedActiveTriggerIdRef = React.useRef(null);
|
|
4680
4389
|
const open = store.useState('open');
|
|
4681
4390
|
const reactiveTriggerCount = store.useState('triggerCount');
|
|
4682
|
-
// Subscribe to the active trigger id so the reconciliation below reruns when ownership moves to
|
|
4683
|
-
// another trigger while the popup stays open (e.g. a focus/hover handoff between triggers).
|
|
4684
|
-
const activeTriggerId = store.useState('activeTriggerId');
|
|
4685
|
-
// Subscribe to the active trigger element so the reconciliation reruns when a pending active
|
|
4686
|
-
// trigger registers in a commit where the trigger count nets out unchanged (registration
|
|
4687
|
-
// forwards the element to the store when the registering trigger matches the active id).
|
|
4688
|
-
// Without this, the id would never be marked resolved and a later genuine unmount would be
|
|
4689
|
-
// misclassified as pending, disabling `closeOnActiveTriggerUnmount`.
|
|
4690
|
-
const reactiveActiveTriggerElement = store.useState('activeTriggerElement');
|
|
4691
4391
|
useIsoLayoutEffect(() => {
|
|
4692
4392
|
if (!open) {
|
|
4693
|
-
resolvedActiveTriggerIdRef.current = null;
|
|
4694
4393
|
if (store.state.triggerCount !== 0) {
|
|
4695
4394
|
store.set('triggerCount', 0);
|
|
4696
4395
|
}
|
|
@@ -4701,42 +4400,22 @@ function useImplicitActiveTrigger(store, options = {}) {
|
|
|
4701
4400
|
if (store.state.triggerCount !== triggerCount) {
|
|
4702
4401
|
stateUpdates.triggerCount = triggerCount;
|
|
4703
4402
|
}
|
|
4704
|
-
const
|
|
4403
|
+
const activeTriggerId = store.select('activeTriggerId');
|
|
4705
4404
|
let lostActiveTriggerId = null;
|
|
4706
|
-
if (
|
|
4707
|
-
const activeTriggerElement = store.context.triggerElements.getById(
|
|
4405
|
+
if (activeTriggerId) {
|
|
4406
|
+
const activeTriggerElement = store.context.triggerElements.getById(activeTriggerId);
|
|
4708
4407
|
if (!activeTriggerElement) {
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
stateUpdates.activeTriggerElement = triggerElement;
|
|
4713
|
-
resolvedActiveTriggerIdRef.current = triggerId;
|
|
4714
|
-
break;
|
|
4715
|
-
}
|
|
4716
|
-
}
|
|
4717
|
-
if (stateUpdates.activeTriggerId === undefined) {
|
|
4718
|
-
if (resolvedActiveTriggerIdRef.current === currentActiveTriggerId) {
|
|
4719
|
-
lostActiveTriggerId = currentActiveTriggerId;
|
|
4720
|
-
} else {
|
|
4721
|
-
resolvedActiveTriggerIdRef.current = null;
|
|
4722
|
-
}
|
|
4723
|
-
}
|
|
4724
|
-
} else {
|
|
4725
|
-
resolvedActiveTriggerIdRef.current = currentActiveTriggerId;
|
|
4726
|
-
if (activeTriggerElement !== store.state.activeTriggerElement) {
|
|
4727
|
-
stateUpdates.activeTriggerElement = activeTriggerElement;
|
|
4728
|
-
}
|
|
4408
|
+
lostActiveTriggerId = activeTriggerId;
|
|
4409
|
+
} else if (activeTriggerElement !== store.state.activeTriggerElement) {
|
|
4410
|
+
stateUpdates.activeTriggerElement = activeTriggerElement;
|
|
4729
4411
|
}
|
|
4730
|
-
} else {
|
|
4731
|
-
resolvedActiveTriggerIdRef.current = null;
|
|
4732
4412
|
}
|
|
4733
|
-
if (!lostActiveTriggerId && !
|
|
4413
|
+
if (!lostActiveTriggerId && !activeTriggerId && triggerCount === 1) {
|
|
4734
4414
|
const iteratorResult = store.context.triggerElements.entries().next();
|
|
4735
4415
|
if (!iteratorResult.done) {
|
|
4736
4416
|
const [implicitTriggerId, implicitTriggerElement] = iteratorResult.value;
|
|
4737
4417
|
stateUpdates.activeTriggerId = implicitTriggerId;
|
|
4738
4418
|
stateUpdates.activeTriggerElement = implicitTriggerElement;
|
|
4739
|
-
resolvedActiveTriggerIdRef.current = implicitTriggerId;
|
|
4740
4419
|
}
|
|
4741
4420
|
}
|
|
4742
4421
|
if (stateUpdates.triggerCount !== undefined || stateUpdates.activeTriggerId !== undefined || stateUpdates.activeTriggerElement !== undefined) {
|
|
@@ -4761,7 +4440,7 @@ function useImplicitActiveTrigger(store, options = {}) {
|
|
|
4761
4440
|
});
|
|
4762
4441
|
}
|
|
4763
4442
|
}
|
|
4764
|
-
}, [open, store, reactiveTriggerCount,
|
|
4443
|
+
}, [open, store, reactiveTriggerCount, closeOnActiveTriggerUnmount]);
|
|
4765
4444
|
}
|
|
4766
4445
|
|
|
4767
4446
|
/**
|
|
@@ -4839,33 +4518,13 @@ function usePopupRootSync(store, open) {
|
|
|
4839
4518
|
}, [store]);
|
|
4840
4519
|
}
|
|
4841
4520
|
|
|
4842
|
-
/**
|
|
4843
|
-
* Development-only reverse index of element to registered id, keyed by the owning map.
|
|
4844
|
-
*
|
|
4845
|
-
* Registration would otherwise have to scan every entry to detect an element claimed by two ids,
|
|
4846
|
-
* making the mount of many triggers sharing one handle quadratic. Kept module-scoped, lazily
|
|
4847
|
-
* initialized, and read only from `process.env.NODE_ENV` guards so production builds drop it along
|
|
4848
|
-
* with the checks.
|
|
4849
|
-
*/
|
|
4850
|
-
let devElementIdsByMap;
|
|
4851
|
-
function getDevElementIds(map) {
|
|
4852
|
-
devElementIdsByMap ??= new WeakMap();
|
|
4853
|
-
let elementIds = devElementIdsByMap.get(map);
|
|
4854
|
-
if (!elementIds) {
|
|
4855
|
-
elementIds = new WeakMap();
|
|
4856
|
-
devElementIdsByMap.set(map, elementIds);
|
|
4857
|
-
}
|
|
4858
|
-
return elementIds;
|
|
4859
|
-
}
|
|
4860
|
-
|
|
4861
4521
|
/**
|
|
4862
4522
|
* Data structure to keep track of popup trigger elements by their IDs.
|
|
4863
|
-
*
|
|
4864
|
-
* Element lookups iterate the id map rather than maintaining a parallel Set. Registration is O(1),
|
|
4865
|
-
* while `hasElement` and `hasMatchingElement` are linear in the number of triggers.
|
|
4523
|
+
* Uses both a set of Elements and a map of IDs to Elements for efficient lookups.
|
|
4866
4524
|
*/
|
|
4867
4525
|
class PopupTriggerMap {
|
|
4868
4526
|
constructor() {
|
|
4527
|
+
this.elementsSet = new Set();
|
|
4869
4528
|
this.idMap = new Map();
|
|
4870
4529
|
}
|
|
4871
4530
|
|
|
@@ -4875,56 +4534,49 @@ class PopupTriggerMap {
|
|
|
4875
4534
|
* Note: The provided element is assumed to not be registered under multiple IDs.
|
|
4876
4535
|
*/
|
|
4877
4536
|
add(id, element) {
|
|
4537
|
+
const existingElement = this.idMap.get(id);
|
|
4538
|
+
if (existingElement === element) {
|
|
4539
|
+
return;
|
|
4540
|
+
}
|
|
4541
|
+
if (existingElement !== undefined) {
|
|
4542
|
+
// We assume that the same element won't be registered under multiple ids.
|
|
4543
|
+
// This is safe considering how useTriggerRegistration is implemented.
|
|
4544
|
+
this.elementsSet.delete(existingElement);
|
|
4545
|
+
}
|
|
4546
|
+
this.elementsSet.add(element);
|
|
4547
|
+
this.idMap.set(id, element);
|
|
4878
4548
|
if (process.env.NODE_ENV !== 'production') {
|
|
4879
|
-
|
|
4880
|
-
const existingId = elementIds.get(element);
|
|
4881
|
-
if (existingId !== undefined && existingId !== id) {
|
|
4549
|
+
if (this.elementsSet.size !== this.idMap.size) {
|
|
4882
4550
|
// TODO: fix mui/no-guarded-throw
|
|
4883
4551
|
// eslint-disable-next-line mui/no-guarded-throw
|
|
4884
4552
|
throw new Error('Base UI: A trigger element cannot be registered under multiple IDs in PopupTriggerMap.');
|
|
4885
4553
|
}
|
|
4886
|
-
|
|
4887
|
-
// Reusing an id for a different element evicts the previous one, so it must lose its claim
|
|
4888
|
-
// on the id or a later registration under a different id would be reported as a duplicate.
|
|
4889
|
-
const previousElement = this.idMap.get(id);
|
|
4890
|
-
if (previousElement !== undefined && previousElement !== element) {
|
|
4891
|
-
elementIds.delete(previousElement);
|
|
4892
|
-
}
|
|
4893
|
-
elementIds.set(element, id);
|
|
4894
4554
|
}
|
|
4895
|
-
this.idMap.set(id, element);
|
|
4896
4555
|
}
|
|
4897
4556
|
|
|
4898
4557
|
/**
|
|
4899
4558
|
* Removes the trigger element with the given ID.
|
|
4900
4559
|
*/
|
|
4901
4560
|
delete(id) {
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
}
|
|
4561
|
+
const element = this.idMap.get(id);
|
|
4562
|
+
if (element) {
|
|
4563
|
+
this.elementsSet.delete(element);
|
|
4564
|
+
this.idMap.delete(id);
|
|
4907
4565
|
}
|
|
4908
|
-
this.idMap.delete(id);
|
|
4909
4566
|
}
|
|
4910
4567
|
|
|
4911
4568
|
/**
|
|
4912
4569
|
* Whether the given element is registered as a trigger.
|
|
4913
4570
|
*/
|
|
4914
4571
|
hasElement(element) {
|
|
4915
|
-
|
|
4916
|
-
if (registered === element) {
|
|
4917
|
-
return true;
|
|
4918
|
-
}
|
|
4919
|
-
}
|
|
4920
|
-
return false;
|
|
4572
|
+
return this.elementsSet.has(element);
|
|
4921
4573
|
}
|
|
4922
4574
|
|
|
4923
4575
|
/**
|
|
4924
4576
|
* Whether there is a registered trigger element matching the given predicate.
|
|
4925
4577
|
*/
|
|
4926
4578
|
hasMatchingElement(predicate) {
|
|
4927
|
-
for (const element of this.
|
|
4579
|
+
for (const element of this.elementsSet) {
|
|
4928
4580
|
if (predicate(element)) {
|
|
4929
4581
|
return true;
|
|
4930
4582
|
}
|
|
@@ -4950,7 +4602,7 @@ class PopupTriggerMap {
|
|
|
4950
4602
|
* Returns an iterable of all registered trigger elements.
|
|
4951
4603
|
*/
|
|
4952
4604
|
elements() {
|
|
4953
|
-
return this.
|
|
4605
|
+
return this.elementsSet.values();
|
|
4954
4606
|
}
|
|
4955
4607
|
|
|
4956
4608
|
/**
|
|
@@ -5010,11 +4662,14 @@ function useValueChanged(value, onChange) {
|
|
|
5010
4662
|
const valueRef = React.useRef(value);
|
|
5011
4663
|
const onChangeCallback = useStableCallback(onChange);
|
|
5012
4664
|
useIsoLayoutEffect(() => {
|
|
5013
|
-
if (valueRef.current
|
|
5014
|
-
|
|
4665
|
+
if (valueRef.current === value) {
|
|
4666
|
+
return;
|
|
5015
4667
|
}
|
|
5016
|
-
valueRef.current
|
|
4668
|
+
onChangeCallback(valueRef.current);
|
|
5017
4669
|
}, [value, onChangeCallback]);
|
|
4670
|
+
useIsoLayoutEffect(() => {
|
|
4671
|
+
valueRef.current = value;
|
|
4672
|
+
}, [value]);
|
|
5018
4673
|
}
|
|
5019
4674
|
|
|
5020
4675
|
function useOpenMethodTriggerProps(open, setOpenMethod) {
|
|
@@ -5057,6 +4712,9 @@ function useOpenInteractionType(open) {
|
|
|
5057
4712
|
}), [openMethod, triggerProps]);
|
|
5058
4713
|
}
|
|
5059
4714
|
|
|
4715
|
+
/**
|
|
4716
|
+
* @internal
|
|
4717
|
+
*/
|
|
5060
4718
|
const DirectionContext = /*#__PURE__*/React.createContext(undefined);
|
|
5061
4719
|
if (process.env.NODE_ENV !== "production") DirectionContext.displayName = "DirectionContext";
|
|
5062
4720
|
function useDirection() {
|
|
@@ -5115,30 +4773,6 @@ function useFocusableWhenDisabled(parameters) {
|
|
|
5115
4773
|
};
|
|
5116
4774
|
}
|
|
5117
4775
|
|
|
5118
|
-
/**
|
|
5119
|
-
* Dispatches a constructed click on the target so it carries the source event's
|
|
5120
|
-
* modifier state, which `click()` always reports as unpressed. Like `click()`,
|
|
5121
|
-
* the untrusted click still runs native activation behavior (form submission,
|
|
5122
|
-
* link navigation).
|
|
5123
|
-
* `detail` defaults to 0 (the native convention for keyboard-generated clicks);
|
|
5124
|
-
* pass `detail: 1` when the click represents a mouse gesture so consumers keying
|
|
5125
|
-
* off `detail === 0` don't classify it as a keyboard activation.
|
|
5126
|
-
*/
|
|
5127
|
-
function dispatchClickWithModifiers(target, sourceEvent, {
|
|
5128
|
-
detail = 0
|
|
5129
|
-
} = {}) {
|
|
5130
|
-
target.dispatchEvent(new (getWindow(target).PointerEvent)('click', {
|
|
5131
|
-
bubbles: true,
|
|
5132
|
-
cancelable: true,
|
|
5133
|
-
composed: true,
|
|
5134
|
-
detail,
|
|
5135
|
-
shiftKey: sourceEvent.shiftKey,
|
|
5136
|
-
ctrlKey: sourceEvent.ctrlKey,
|
|
5137
|
-
altKey: sourceEvent.altKey,
|
|
5138
|
-
metaKey: sourceEvent.metaKey
|
|
5139
|
-
}));
|
|
5140
|
-
}
|
|
5141
|
-
|
|
5142
4776
|
function useButton(parameters = {}) {
|
|
5143
4777
|
const {
|
|
5144
4778
|
disabled = false,
|
|
@@ -5239,34 +4873,24 @@ function useButton(parameters = {}) {
|
|
|
5239
4873
|
return;
|
|
5240
4874
|
}
|
|
5241
4875
|
event.preventDefault();
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
4876
|
+
if (isLink || isNativeButton && isButton) {
|
|
4877
|
+
currentTarget.click();
|
|
4878
|
+
event.preventBaseUIHandler();
|
|
4879
|
+
} else if (shouldClick) {
|
|
4880
|
+
externalOnClick?.(event);
|
|
5245
4881
|
event.preventBaseUIHandler();
|
|
5246
|
-
dispatchClickWithModifiers(currentTarget, event);
|
|
5247
4882
|
}
|
|
5248
4883
|
return;
|
|
5249
4884
|
}
|
|
5250
4885
|
|
|
5251
4886
|
// Keyboard accessibility for native and non-native elements.
|
|
5252
|
-
if (
|
|
5253
|
-
|
|
5254
|
-
// composite path); prevent the page scroll Space would otherwise trigger.
|
|
5255
|
-
// Enter is left to the browser's native link activation.
|
|
5256
|
-
if (isCurrentTarget && isLink && isSpaceKey) {
|
|
4887
|
+
if (shouldClick) {
|
|
4888
|
+
if (!isNativeButton && (isSpaceKey || isEnterKey)) {
|
|
5257
4889
|
event.preventDefault();
|
|
5258
4890
|
}
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
// Match native buttons: preventing the keydown's default cancels activation.
|
|
5263
|
-
if (event.defaultPrevented) {
|
|
5264
|
-
return;
|
|
5265
|
-
}
|
|
5266
|
-
event.preventDefault();
|
|
5267
|
-
if (isEnterKey) {
|
|
5268
|
-
event.preventBaseUIHandler();
|
|
5269
|
-
dispatchClickWithModifiers(currentTarget, event);
|
|
4891
|
+
if (!isNativeButton && isEnterKey) {
|
|
4892
|
+
externalOnClick?.(event);
|
|
4893
|
+
}
|
|
5270
4894
|
}
|
|
5271
4895
|
},
|
|
5272
4896
|
onKeyUp(event) {
|
|
@@ -5286,14 +4910,9 @@ function useButton(parameters = {}) {
|
|
|
5286
4910
|
return;
|
|
5287
4911
|
}
|
|
5288
4912
|
|
|
5289
|
-
// Keyboard accessibility for non interactive elements
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
// activation — no state is kept between keydown and keyup, so we can't tell
|
|
5293
|
-
// whether the keydown was prevented or even happened on this element.
|
|
5294
|
-
if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && !event.defaultPrevented && event.key === ' ') {
|
|
5295
|
-
event.preventBaseUIHandler();
|
|
5296
|
-
dispatchClickWithModifiers(event.currentTarget, event);
|
|
4913
|
+
// Keyboard accessibility for non interactive elements
|
|
4914
|
+
if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === ' ') {
|
|
4915
|
+
externalOnClick?.(event);
|
|
5297
4916
|
}
|
|
5298
4917
|
},
|
|
5299
4918
|
onPointerDown(event) {
|
|
@@ -5322,38 +4941,9 @@ function isButtonElement(elem) {
|
|
|
5322
4941
|
return isHTMLElement(elem) && elem.tagName === 'BUTTON';
|
|
5323
4942
|
}
|
|
5324
4943
|
function isValidLinkElement(elem) {
|
|
5325
|
-
return
|
|
4944
|
+
return Boolean(elem?.tagName === 'A' && elem?.href);
|
|
5326
4945
|
}
|
|
5327
4946
|
|
|
5328
|
-
let TransitionStatusDataAttributes = /*#__PURE__*/function (TransitionStatusDataAttributes) {
|
|
5329
|
-
/**
|
|
5330
|
-
* Present when the component begins animating in.
|
|
5331
|
-
*/
|
|
5332
|
-
TransitionStatusDataAttributes["startingStyle"] = "data-starting-style";
|
|
5333
|
-
/**
|
|
5334
|
-
* Present when the component is animating out.
|
|
5335
|
-
*/
|
|
5336
|
-
TransitionStatusDataAttributes["endingStyle"] = "data-ending-style";
|
|
5337
|
-
return TransitionStatusDataAttributes;
|
|
5338
|
-
}({});
|
|
5339
|
-
const STARTING_HOOK = {
|
|
5340
|
-
'data-starting-style': ''
|
|
5341
|
-
};
|
|
5342
|
-
const ENDING_HOOK = {
|
|
5343
|
-
'data-ending-style': ''
|
|
5344
|
-
};
|
|
5345
|
-
const transitionStatusMapping = {
|
|
5346
|
-
transitionStatus(value) {
|
|
5347
|
-
if (value === 'starting') {
|
|
5348
|
-
return STARTING_HOOK;
|
|
5349
|
-
}
|
|
5350
|
-
if (value === 'ending') {
|
|
5351
|
-
return ENDING_HOOK;
|
|
5352
|
-
}
|
|
5353
|
-
return null;
|
|
5354
|
-
}
|
|
5355
|
-
};
|
|
5356
|
-
|
|
5357
4947
|
let CommonPopupDataAttributes = function (CommonPopupDataAttributes) {
|
|
5358
4948
|
/**
|
|
5359
4949
|
* Present when the popup is open.
|
|
@@ -5364,7 +4954,7 @@ let CommonPopupDataAttributes = function (CommonPopupDataAttributes) {
|
|
|
5364
4954
|
*/
|
|
5365
4955
|
CommonPopupDataAttributes["closed"] = "data-closed";
|
|
5366
4956
|
/**
|
|
5367
|
-
* Present when the popup
|
|
4957
|
+
* Present when the popup is animating in.
|
|
5368
4958
|
*/
|
|
5369
4959
|
CommonPopupDataAttributes[CommonPopupDataAttributes["startingStyle"] = TransitionStatusDataAttributes.startingStyle] = "startingStyle";
|
|
5370
4960
|
/**
|
|
@@ -5387,24 +4977,32 @@ let CommonPopupDataAttributes = function (CommonPopupDataAttributes) {
|
|
|
5387
4977
|
CommonPopupDataAttributes["align"] = "data-align";
|
|
5388
4978
|
return CommonPopupDataAttributes;
|
|
5389
4979
|
}({});
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
4980
|
+
let CommonTriggerDataAttributes = /*#__PURE__*/function (CommonTriggerDataAttributes) {
|
|
4981
|
+
/**
|
|
4982
|
+
* Present when the popup is open.
|
|
4983
|
+
*/
|
|
4984
|
+
CommonTriggerDataAttributes["popupOpen"] = "data-popup-open";
|
|
4985
|
+
/**
|
|
4986
|
+
* Present when a pressable trigger is pressed.
|
|
4987
|
+
*/
|
|
4988
|
+
CommonTriggerDataAttributes["pressed"] = "data-pressed";
|
|
4989
|
+
return CommonTriggerDataAttributes;
|
|
4990
|
+
}({});
|
|
5393
4991
|
const TRIGGER_HOOK = {
|
|
5394
|
-
|
|
4992
|
+
[CommonTriggerDataAttributes.popupOpen]: ''
|
|
5395
4993
|
};
|
|
5396
4994
|
const PRESSABLE_TRIGGER_HOOK = {
|
|
5397
|
-
|
|
5398
|
-
|
|
4995
|
+
[CommonTriggerDataAttributes.popupOpen]: '',
|
|
4996
|
+
[CommonTriggerDataAttributes.pressed]: ''
|
|
5399
4997
|
};
|
|
5400
4998
|
const POPUP_OPEN_HOOK = {
|
|
5401
|
-
|
|
4999
|
+
[CommonPopupDataAttributes.open]: ''
|
|
5402
5000
|
};
|
|
5403
5001
|
const POPUP_CLOSED_HOOK = {
|
|
5404
|
-
|
|
5002
|
+
[CommonPopupDataAttributes.closed]: ''
|
|
5405
5003
|
};
|
|
5406
5004
|
const ANCHOR_HIDDEN_HOOK = {
|
|
5407
|
-
|
|
5005
|
+
[CommonPopupDataAttributes.anchorHidden]: ''
|
|
5408
5006
|
};
|
|
5409
5007
|
const triggerOpenStateMapping = {
|
|
5410
5008
|
open(value) {
|
|
@@ -5436,10 +5034,6 @@ const popupStateMapping = {
|
|
|
5436
5034
|
return null;
|
|
5437
5035
|
}
|
|
5438
5036
|
};
|
|
5439
|
-
const popupTransitionStateMapping = {
|
|
5440
|
-
...popupStateMapping,
|
|
5441
|
-
...transitionStatusMapping
|
|
5442
|
-
};
|
|
5443
5037
|
|
|
5444
5038
|
function inertValue(value) {
|
|
5445
5039
|
if (isReactVersionAtLeast(19)) {
|
|
@@ -5481,15 +5075,6 @@ if (process.env.NODE_ENV !== "production") InternalBackdrop.displayName = "Inter
|
|
|
5481
5075
|
let originalHtmlStyles = {};
|
|
5482
5076
|
let originalBodyStyles = {};
|
|
5483
5077
|
let originalHtmlScrollBehavior = '';
|
|
5484
|
-
|
|
5485
|
-
// The viewport's overflow comes from <html> when it establishes its own scroll container, and
|
|
5486
|
-
// propagates from <body> otherwise. An `overflow` style on the other element doesn't lock the page.
|
|
5487
|
-
function getViewportScroller(html, body) {
|
|
5488
|
-
return isOverflowElement(html) ? html : body;
|
|
5489
|
-
}
|
|
5490
|
-
function isPageScrollLocked(win, html, body) {
|
|
5491
|
-
return /hidden|clip/.test(win.getComputedStyle(getViewportScroller(html, body)).overflowY);
|
|
5492
|
-
}
|
|
5493
5078
|
function hasInsetScrollbars(referenceElement) {
|
|
5494
5079
|
if (typeof document === 'undefined') {
|
|
5495
5080
|
return false;
|
|
@@ -5506,7 +5091,7 @@ function supportsStableScrollbarGutter(referenceElement) {
|
|
|
5506
5091
|
const doc = ownerDocument(referenceElement);
|
|
5507
5092
|
const html = doc.documentElement;
|
|
5508
5093
|
const body = doc.body;
|
|
5509
|
-
const scrollContainer =
|
|
5094
|
+
const scrollContainer = isOverflowElement(html) ? html : body;
|
|
5510
5095
|
const originalScrollContainerOverflowY = scrollContainer.style.overflowY;
|
|
5511
5096
|
const originalHtmlStyleGutter = html.style.scrollbarGutter;
|
|
5512
5097
|
html.style.scrollbarGutter = 'stable';
|
|
@@ -5527,7 +5112,7 @@ function preventScrollOverlayScrollbars(referenceElement) {
|
|
|
5527
5112
|
// won't have any effect.
|
|
5528
5113
|
// But if <body> has an `overflow` style (like `overflow-x: hidden`), we need to lock it
|
|
5529
5114
|
// instead, as sticky elements shift otherwise.
|
|
5530
|
-
const elementToLock =
|
|
5115
|
+
const elementToLock = isOverflowElement(html) ? html : body;
|
|
5531
5116
|
const originalElementToLockStyles = {
|
|
5532
5117
|
overflowY: elementToLock.style.overflowY,
|
|
5533
5118
|
overflowX: elementToLock.style.overflowX
|
|
@@ -5592,7 +5177,7 @@ function preventScrollInsetScrollbars(referenceElement) {
|
|
|
5592
5177
|
// with whitespace. Warn if <body> has margins?
|
|
5593
5178
|
const marginY = parseFloat(bodyStyles.marginTop) + parseFloat(bodyStyles.marginBottom);
|
|
5594
5179
|
const marginX = parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight);
|
|
5595
|
-
const elementToLock =
|
|
5180
|
+
const elementToLock = isOverflowElement(html) ? html : body;
|
|
5596
5181
|
updateGutterOnly = supportsStableScrollbarGutter(referenceElement);
|
|
5597
5182
|
|
|
5598
5183
|
/*
|
|
@@ -5622,9 +5207,7 @@ function preventScrollInsetScrollbars(referenceElement) {
|
|
|
5622
5207
|
height: marginY || scrollbarHeight ? `calc(100dvh - ${marginY + scrollbarHeight}px)` : '100dvh',
|
|
5623
5208
|
width: marginX || scrollbarWidth ? `calc(100vw - ${marginX + scrollbarWidth}px)` : '100vw',
|
|
5624
5209
|
boxSizing: 'border-box',
|
|
5625
|
-
|
|
5626
|
-
overflowY: 'hidden',
|
|
5627
|
-
overflowX: 'hidden',
|
|
5210
|
+
overflow: 'hidden',
|
|
5628
5211
|
scrollBehavior: 'unset'
|
|
5629
5212
|
});
|
|
5630
5213
|
body.scrollTop = scrollTop;
|
|
@@ -5689,30 +5272,11 @@ class ScrollLocker {
|
|
|
5689
5272
|
}
|
|
5690
5273
|
const doc = ownerDocument(referenceElement);
|
|
5691
5274
|
const html = doc.documentElement;
|
|
5692
|
-
const
|
|
5693
|
-
const win = getWindow(html);
|
|
5694
|
-
|
|
5695
|
-
// The page is already locked, either by the site author or by a non-Base UI overlay that
|
|
5696
|
-
// hasn't cleaned up yet. Leave it alone and wait for the lock to clear before taking over,
|
|
5697
|
-
// otherwise we'd snapshot the locked state and restore it after our own lock is released.
|
|
5698
|
-
if (isPageScrollLocked(win, html, body)) {
|
|
5699
|
-
const observer = new win.MutationObserver(() => {
|
|
5700
|
-
if (isPageScrollLocked(win, html, body)) {
|
|
5701
|
-
return;
|
|
5702
|
-
}
|
|
5703
|
-
observer.disconnect();
|
|
5704
|
-
this.restore = null;
|
|
5705
|
-
this.lock(referenceElement);
|
|
5706
|
-
});
|
|
5275
|
+
const htmlOverflowY = getWindow(html).getComputedStyle(html).overflowY;
|
|
5707
5276
|
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
attributes: true
|
|
5712
|
-
};
|
|
5713
|
-
observer.observe(html, options);
|
|
5714
|
-
observer.observe(body, options);
|
|
5715
|
-
this.restore = () => observer.disconnect();
|
|
5277
|
+
// If the site author already hid overflow on <html>, respect it and bail out.
|
|
5278
|
+
if (htmlOverflowY === 'hidden' || htmlOverflowY === 'clip') {
|
|
5279
|
+
this.restore = NOOP;
|
|
5716
5280
|
return;
|
|
5717
5281
|
}
|
|
5718
5282
|
const hasOverlayScrollbars = ios || !hasInsetScrollbars(referenceElement);
|
|
@@ -5743,4 +5307,4 @@ function useScrollLock(enabled = true, referenceElement = null) {
|
|
|
5743
5307
|
}, [enabled, referenceElement]);
|
|
5744
5308
|
}
|
|
5745
5309
|
|
|
5746
|
-
export {
|
|
5310
|
+
export { cancelOpen as $, inputBlur as A, inputPaste as B, CommonPopupDataAttributes as C, activeElement as D, createGenericEventDetails as E, FOCUSABLE_POPUP_PROPS as F, wheel as G, useOnMount as H, incrementPress as I, decrementPress as J, useValueChanged as K, stopEvent as L, keyboard as M, createSelector as N, useOpenInteractionType as O, useStore as P, useClick as Q, useDismiss as R, SafeReact as S, Timeout as T, useOnFirstRender as U, Store as V, focusOut as W, outsidePress as X, pressableTriggerOpenStateMapping as Y, getFloatingFocusElement as Z, contains as _, useIsoLayoutEffect as a, getTabbableBeforeElement as a$, FloatingPortal as a0, InternalBackdrop as a1, inertValue as a2, DROPDOWN_COLLISION_AVOIDANCE as a3, useDirection as a4, useAnimationFrame as a5, webkit as a6, windowResize as a7, isVirtualClick as a8, itemPress as a9, isTargetInsideEnabledTrigger as aA, triggerFocus as aB, createAttribute as aC, mac as aD, triggerPress as aE, escapeKey as aF, isInteractiveElement as aG, getNodeChildren as aH, triggerHover as aI, useAnimationsFinished as aJ, POPUP_COLLISION_AVOIDANCE as aK, FloatingNode as aL, siblingOpen as aM, ReactStore as aN, FloatingTreeStore as aO, fastComponent as aP, useInitialOpenSync as aQ, useFloatingNodeId as aR, useImplicitActiveTrigger as aS, useOpenStateTransitions as aT, attachPreventUnmountOnClose as aU, setPopupOpenState as aV, useSyncedFloatingRootContext as aW, TYPEAHEAD_RESET_MS as aX, usePopupInteractionProps as aY, FloatingTree as aZ, useCompositeRootContext as a_, useId as aa, useFloatingParentNodeId as ab, FloatingRootStore as ac, PopupTriggerMap as ad, useFloatingTree as ae, isTypeableCombobox as af, isIndexOutOfListBounds as ag, getMinListIndex as ah, getMaxListIndex as ai, listNavigation as aj, findNonDisabledListIndex as ak, enqueueFocus as al, isVirtualPointerEvent as am, ARROW_UP as an, ARROW_DOWN as ao, ARROW_LEFT as ap, ARROW_RIGHT as aq, isListIndexDisabled as ar, isElementVisible as as, jsdom as at, DISABLED_TRANSITIONS_STYLE as au, useScrollLock as av, isMouseLikePointerType as aw, mergeCleanups as ax, isTypeableElement as ay, matchesFocusVisible as az, useStableCallback as b, isOutsideEvent as b0, getTabbableAfterElement as b1, getNextTabbable as b2, fastComponentRef as b3, useTriggerDataForwarding as b4, FocusGuard as b5, PATIENT_CLICK_THRESHOLD as b6, useTriggerRegistration as b7, triggerOpenStateMapping as b8, usePopupRootSync as b9, usePopupStore as ba, useOpenMethodTriggerProps as bb, CLICK_TRIGGER_IDENTIFIER as bc, android as bd, closeWatcher as be, BASE_UI_SWIPE_IGNORE_SELECTOR as bf, TransitionStatusDataAttributes as bg, swipe as bh, getGridNavigatedIndex as bi, inputPress as bj, gecko as bk, clearPress as bl, chipRemovePress as bm, pointer as bn, scrub as bo, useButton as c, createChangeEventDetails as d, closePress as e, useOpenChangeComplete as f, getTarget as g, createDefaultInitialFocus as h, FloatingFocusManager as i, imperativeAction as j, useTimeout as k, error as l, useTransitionStatus as m, useControlled as n, ownerDocument as o, popupStateMapping as p, useValueAsRef as q, ios as r, addEventListener as s, transitionStatusMapping as t, useBaseUiId as u, none as v, visuallyHiddenInput as w, visuallyHidden as x, inputChange as y, inputClear as z };
|