@mui/material 7.3.10 → 7.3.11
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/Autocomplete/Autocomplete.js +63 -12
- package/Button/Button.js +18 -1
- package/CHANGELOG.md +35 -0
- package/Checkbox/Checkbox.js +2 -1
- package/ClickAwayListener/ClickAwayListener.js +2 -5
- package/Dialog/Dialog.js +11 -6
- package/Drawer/Drawer.js +18 -4
- package/Fab/Fab.js +7 -1
- package/InputBase/InputBase.js +39 -7
- package/ListItemButton/ListItemButton.js +7 -1
- package/MenuItem/MenuItem.js +6 -1
- package/Popper/BasePopper.js +23 -1
- package/Slider/useSlider.js +6 -3
- package/SwipeableDrawer/SwipeableDrawer.js +5 -4
- package/Switch/Switch.js +3 -4
- package/Unstable_TrapFocus/FocusTrap.js +15 -5
- package/esm/Autocomplete/Autocomplete.js +63 -12
- package/esm/Button/Button.js +18 -1
- package/esm/Checkbox/Checkbox.js +2 -1
- package/esm/ClickAwayListener/ClickAwayListener.js +2 -5
- package/esm/Dialog/Dialog.js +11 -6
- package/esm/Drawer/Drawer.js +18 -4
- package/esm/Fab/Fab.js +7 -1
- package/esm/InputBase/InputBase.js +39 -7
- package/esm/ListItemButton/ListItemButton.js +7 -1
- package/esm/MenuItem/MenuItem.js +6 -1
- package/esm/Popper/BasePopper.js +23 -1
- package/esm/Slider/useSlider.js +6 -3
- package/esm/SwipeableDrawer/SwipeableDrawer.js +5 -4
- package/esm/Switch/Switch.js +3 -4
- package/esm/Unstable_TrapFocus/FocusTrap.js +15 -5
- package/esm/index.js +1 -1
- package/esm/useAutocomplete/useAutocomplete.d.ts +4 -5
- package/esm/useAutocomplete/useAutocomplete.js +155 -46
- package/esm/utils/contains.d.ts +2 -0
- package/esm/utils/contains.js +2 -0
- package/esm/utils/focusable.d.ts +7 -0
- package/esm/utils/focusable.js +13 -0
- package/esm/utils/getEventTarget.d.ts +2 -0
- package/esm/utils/getEventTarget.js +2 -0
- package/esm/version/index.js +2 -2
- package/index.js +1 -1
- package/package.json +5 -5
- package/useAutocomplete/useAutocomplete.d.ts +4 -5
- package/useAutocomplete/useAutocomplete.js +155 -46
- package/utils/contains.d.ts +2 -0
- package/utils/contains.js +9 -0
- package/utils/focusable.d.ts +7 -0
- package/utils/focusable.js +20 -0
- package/utils/getEventTarget.d.ts +2 -0
- package/utils/getEventTarget.js +9 -0
- package/version/index.js +2 -2
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
9
9
|
exports.createFilterOptions = createFilterOptions;
|
|
10
10
|
exports.default = void 0;
|
|
11
11
|
var React = _interopRequireWildcard(require("react"));
|
|
12
|
+
var _contains = _interopRequireDefault(require("@mui/utils/contains"));
|
|
12
13
|
var _setRef = _interopRequireDefault(require("@mui/utils/setRef"));
|
|
13
14
|
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
|
|
14
15
|
var _useControlled = _interopRequireDefault(require("@mui/utils/useControlled"));
|
|
@@ -63,7 +64,7 @@ const defaultFilterOptions = createFilterOptions();
|
|
|
63
64
|
|
|
64
65
|
// Number of options to jump in list box when `Page Up` and `Page Down` keys are used.
|
|
65
66
|
const pageSize = 5;
|
|
66
|
-
const defaultIsActiveElementInListbox = listboxRef => listboxRef.current !== null && listboxRef.current.parentElement
|
|
67
|
+
const defaultIsActiveElementInListbox = listboxRef => listboxRef.current !== null && (0, _contains.default)(listboxRef.current.parentElement, document.activeElement);
|
|
67
68
|
const defaultIsOptionEqualToValue = (option, value) => option === value;
|
|
68
69
|
const MULTIPLE_DEFAULT_VALUE = [];
|
|
69
70
|
function getInputValue(value, multiple, getOptionLabel, renderValue) {
|
|
@@ -141,6 +142,20 @@ function useAutocomplete(props) {
|
|
|
141
142
|
const defaultHighlighted = autoHighlight ? 0 : -1;
|
|
142
143
|
const highlightedIndexRef = React.useRef(defaultHighlighted);
|
|
143
144
|
|
|
145
|
+
// Tracks how the current highlight was set:
|
|
146
|
+
// - 'keyboard' — arrow keys, Home/End, PageUp/PageDown
|
|
147
|
+
// - 'mouse' — handleOptionMouseMove
|
|
148
|
+
// - 'touch' — handleOptionTouchStart
|
|
149
|
+
// - null — programmatic (autoHighlight, value sync)
|
|
150
|
+
//
|
|
151
|
+
// This lets handleBlur and the Enter handler distinguish intentional
|
|
152
|
+
// interactions from incidental ones — e.g. autoSelect should not commit
|
|
153
|
+
// a highlight that came from a casual mouse hover.
|
|
154
|
+
/** @type {React.RefObject<AutocompleteHighlightChangeReason | null>} */
|
|
155
|
+
const highlightReasonRef = React.useRef(null);
|
|
156
|
+
const touchScrolledRef = React.useRef(false);
|
|
157
|
+
const isTouchRef = React.useRef(false);
|
|
158
|
+
|
|
144
159
|
// Calculate the initial inputValue on mount only.
|
|
145
160
|
// useRef ensures it doesn't update dynamically with defaultValue or value props.
|
|
146
161
|
const initialInputValue = React.useRef(getInputValue(defaultValue ?? valueProp, multiple, getOptionLabel)).current;
|
|
@@ -280,22 +295,17 @@ function useAutocomplete(props) {
|
|
|
280
295
|
}
|
|
281
296
|
}
|
|
282
297
|
}
|
|
283
|
-
const
|
|
284
|
-
event,
|
|
298
|
+
const syncHighlightedIndexToDOM = (0, _useEventCallback.default)(({
|
|
285
299
|
index,
|
|
286
|
-
reason
|
|
300
|
+
reason,
|
|
301
|
+
preserveScroll = false
|
|
287
302
|
}) => {
|
|
288
|
-
highlightedIndexRef.current = index;
|
|
289
|
-
|
|
290
303
|
// does the index exist?
|
|
291
304
|
if (index === -1) {
|
|
292
305
|
inputRef.current.removeAttribute('aria-activedescendant');
|
|
293
306
|
} else {
|
|
294
307
|
inputRef.current.setAttribute('aria-activedescendant', `${id}-option-${index}`);
|
|
295
308
|
}
|
|
296
|
-
if (onHighlightChange && ['mouse', 'keyboard', 'touch'].includes(reason)) {
|
|
297
|
-
onHighlightChange(event, index === -1 ? null : filteredOptions[index], reason);
|
|
298
|
-
}
|
|
299
309
|
if (!listboxRef.current) {
|
|
300
310
|
return;
|
|
301
311
|
}
|
|
@@ -314,7 +324,9 @@ function useAutocomplete(props) {
|
|
|
314
324
|
return;
|
|
315
325
|
}
|
|
316
326
|
if (index === -1) {
|
|
317
|
-
|
|
327
|
+
if (!preserveScroll) {
|
|
328
|
+
listboxNode.scrollTop = 0;
|
|
329
|
+
}
|
|
318
330
|
return;
|
|
319
331
|
}
|
|
320
332
|
const option = listboxRef.current.querySelector(`[data-option-index="${index}"]`);
|
|
@@ -342,15 +354,46 @@ function useAutocomplete(props) {
|
|
|
342
354
|
}
|
|
343
355
|
}
|
|
344
356
|
});
|
|
357
|
+
const setHighlightedIndex = (0, _useEventCallback.default)(({
|
|
358
|
+
event,
|
|
359
|
+
index,
|
|
360
|
+
reason,
|
|
361
|
+
preserveScroll = false
|
|
362
|
+
}) => {
|
|
363
|
+
highlightedIndexRef.current = index;
|
|
364
|
+
highlightReasonRef.current = reason ?? null;
|
|
365
|
+
if (onHighlightChange && ['mouse', 'keyboard', 'touch'].includes(reason)) {
|
|
366
|
+
onHighlightChange(event, index === -1 ? null : filteredOptions[index], reason);
|
|
367
|
+
}
|
|
368
|
+
syncHighlightedIndexToDOM({
|
|
369
|
+
index,
|
|
370
|
+
reason,
|
|
371
|
+
preserveScroll
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
const setHighlightedIndexFromSync = (0, _useEventCallback.default)(({
|
|
375
|
+
index
|
|
376
|
+
}) => {
|
|
377
|
+
highlightedIndexRef.current = index;
|
|
378
|
+
syncHighlightedIndexToDOM({
|
|
379
|
+
index,
|
|
380
|
+
reason: highlightReasonRef.current
|
|
381
|
+
});
|
|
382
|
+
});
|
|
345
383
|
const changeHighlightedIndex = (0, _useEventCallback.default)(({
|
|
346
384
|
event,
|
|
347
385
|
diff,
|
|
348
386
|
direction = 'next',
|
|
349
|
-
reason
|
|
387
|
+
reason,
|
|
388
|
+
preserveScroll
|
|
350
389
|
}) => {
|
|
351
390
|
if (!popupOpen) {
|
|
352
391
|
return;
|
|
353
392
|
}
|
|
393
|
+
if (reason === 'keyboard') {
|
|
394
|
+
touchScrolledRef.current = false;
|
|
395
|
+
isTouchRef.current = false;
|
|
396
|
+
}
|
|
354
397
|
const getNextIndex = () => {
|
|
355
398
|
const maxIndex = filteredOptions.length - 1;
|
|
356
399
|
if (diff === 'reset') {
|
|
@@ -387,7 +430,8 @@ function useAutocomplete(props) {
|
|
|
387
430
|
setHighlightedIndex({
|
|
388
431
|
index: nextIndex,
|
|
389
432
|
reason,
|
|
390
|
-
event
|
|
433
|
+
event,
|
|
434
|
+
preserveScroll
|
|
391
435
|
});
|
|
392
436
|
|
|
393
437
|
// Sync the content of the input with the highlighted option.
|
|
@@ -441,15 +485,24 @@ function useAutocomplete(props) {
|
|
|
441
485
|
// If it exists and the value and the inputValue haven't changed, just update its index, otherwise continue execution
|
|
442
486
|
const previousHighlightedOptionIndex = getPreviousHighlightedOptionIndex();
|
|
443
487
|
if (previousHighlightedOptionIndex !== -1) {
|
|
444
|
-
|
|
488
|
+
// Keep the original highlight reason while re-syncing the DOM state.
|
|
489
|
+
// The highlighted option still exists after the filteredOptions array changed
|
|
490
|
+
// (e.g. async fetch returns new options while the user is mid-navigation),
|
|
491
|
+
// so the original interaction reason (keyboard, mouse, etc.) still applies.
|
|
492
|
+
setHighlightedIndexFromSync({
|
|
493
|
+
index: previousHighlightedOptionIndex
|
|
494
|
+
});
|
|
445
495
|
return;
|
|
446
496
|
}
|
|
447
497
|
const valueItem = multiple ? value[0] : value;
|
|
448
498
|
|
|
449
499
|
// The popup is empty, reset
|
|
450
500
|
if (filteredOptions.length === 0 || valueItem == null) {
|
|
501
|
+
// Preserve scroll when new options are appended without changing the current filter.
|
|
502
|
+
const isAppendOnly = filteredOptionsChanged && previousProps.inputValue === inputValue && previousProps.filteredOptions?.length > 0 && filteredOptions.length > previousProps.filteredOptions.length && previousProps.filteredOptions.every((option, index) => getOptionLabel(option) === getOptionLabel(filteredOptions[index]));
|
|
451
503
|
changeHighlightedIndex({
|
|
452
|
-
diff: 'reset'
|
|
504
|
+
diff: 'reset',
|
|
505
|
+
preserveScroll: isAppendOnly
|
|
453
506
|
});
|
|
454
507
|
return;
|
|
455
508
|
}
|
|
@@ -461,8 +514,12 @@ function useAutocomplete(props) {
|
|
|
461
514
|
if (valueItem != null) {
|
|
462
515
|
const currentOption = filteredOptions[highlightedIndexRef.current];
|
|
463
516
|
|
|
464
|
-
// Keep the current
|
|
465
|
-
|
|
517
|
+
// Keep the current selected highlight while the popup stays open;
|
|
518
|
+
// on reopen, resync from the selected value.
|
|
519
|
+
if (multiple && currentOption && value.findIndex(val => isOptionEqualToValue(currentOption, val)) !== -1 && previousProps.filteredOptions?.length > 0) {
|
|
520
|
+
setHighlightedIndexFromSync({
|
|
521
|
+
index: highlightedIndexRef.current
|
|
522
|
+
});
|
|
466
523
|
return;
|
|
467
524
|
}
|
|
468
525
|
const itemIndex = filteredOptions.findIndex(optionItem => isOptionEqualToValue(optionItem, valueItem));
|
|
@@ -497,7 +554,7 @@ function useAutocomplete(props) {
|
|
|
497
554
|
filteredOptions.length,
|
|
498
555
|
// Don't sync the highlighted index with the value when multiple
|
|
499
556
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
500
|
-
multiple ? false : value, changeHighlightedIndex, setHighlightedIndex, popupOpen, inputValue, multiple]);
|
|
557
|
+
multiple ? false : value, changeHighlightedIndex, setHighlightedIndex, setHighlightedIndexFromSync, popupOpen, inputValue, multiple]);
|
|
501
558
|
const handleListboxRef = (0, _useEventCallback.default)(node => {
|
|
502
559
|
(0, _setRef.default)(listboxRef, node);
|
|
503
560
|
if (!node) {
|
|
@@ -543,6 +600,7 @@ function useAutocomplete(props) {
|
|
|
543
600
|
}
|
|
544
601
|
setOpenState(true);
|
|
545
602
|
setInputPristine(true);
|
|
603
|
+
isTouchRef.current = false;
|
|
546
604
|
if (onOpen) {
|
|
547
605
|
onOpen(event);
|
|
548
606
|
}
|
|
@@ -552,6 +610,8 @@ function useAutocomplete(props) {
|
|
|
552
610
|
return;
|
|
553
611
|
}
|
|
554
612
|
setOpenState(false);
|
|
613
|
+
touchScrolledRef.current = false;
|
|
614
|
+
highlightReasonRef.current = null;
|
|
555
615
|
if (onClose) {
|
|
556
616
|
onClose(event, reason);
|
|
557
617
|
}
|
|
@@ -569,7 +629,6 @@ function useAutocomplete(props) {
|
|
|
569
629
|
}
|
|
570
630
|
setValueState(newValue);
|
|
571
631
|
};
|
|
572
|
-
const isTouch = React.useRef(false);
|
|
573
632
|
const selectNewValue = (event, option, reasonProp = 'selectOption', origin = 'options') => {
|
|
574
633
|
let reason = reasonProp;
|
|
575
634
|
let newValue = option;
|
|
@@ -596,7 +655,7 @@ function useAutocomplete(props) {
|
|
|
596
655
|
if (!disableCloseOnSelect && (!event || !event.ctrlKey && !event.metaKey)) {
|
|
597
656
|
handleClose(event, reason);
|
|
598
657
|
}
|
|
599
|
-
if (blurOnSelect === true || blurOnSelect === 'touch' &&
|
|
658
|
+
if (blurOnSelect === true || blurOnSelect === 'touch' && isTouchRef.current || blurOnSelect === 'mouse' && !isTouchRef.current) {
|
|
600
659
|
inputRef.current.blur();
|
|
601
660
|
}
|
|
602
661
|
};
|
|
@@ -785,29 +844,47 @@ function useAutocomplete(props) {
|
|
|
785
844
|
}
|
|
786
845
|
break;
|
|
787
846
|
case 'Enter':
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
847
|
+
{
|
|
848
|
+
// In freeSolo, only select the highlighted option if the user hasn't
|
|
849
|
+
// typed new text (inputPristine) or explicitly interacted with an option
|
|
850
|
+
// (keyboard, mouse, or touch — any non-null reason). This lets typed
|
|
851
|
+
// text win over a programmatic highlight (reason=null, e.g. from
|
|
852
|
+
// syncHighlightedIndex matching a previous value) while still honoring
|
|
853
|
+
// deliberate user interactions like hovering a suggestion then pressing Enter.
|
|
854
|
+
const shouldSelectHighlighted = !freeSolo || inputPristine || highlightReasonRef.current !== null;
|
|
855
|
+
if (highlightedIndexRef.current !== -1 && popupOpen && shouldSelectHighlighted &&
|
|
856
|
+
// After a touch-scroll the highlight is stale (the user scrolled
|
|
857
|
+
// past it), so skip selection until the next deliberate interaction.
|
|
858
|
+
!touchScrolledRef.current) {
|
|
859
|
+
const option = filteredOptions[highlightedIndexRef.current];
|
|
860
|
+
const disabled = getOptionDisabled ? getOptionDisabled(option) : false;
|
|
791
861
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
862
|
+
// Avoid early form validation, let the end-users continue filling the form.
|
|
863
|
+
event.preventDefault();
|
|
864
|
+
if (disabled) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
selectNewValue(event, option, 'selectOption');
|
|
798
868
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
869
|
+
// Move the selection to the end.
|
|
870
|
+
if (autoComplete) {
|
|
871
|
+
inputRef.current.setSelectionRange(inputRef.current.value.length, inputRef.current.value.length);
|
|
872
|
+
}
|
|
873
|
+
} else if (freeSolo && inputValue !== '' && inputValueIsSelectedValue === false) {
|
|
874
|
+
if (multiple) {
|
|
875
|
+
// Allow people to add new values before they submit the form.
|
|
876
|
+
event.preventDefault();
|
|
877
|
+
}
|
|
878
|
+
selectNewValue(event, inputValue, 'createOption', 'freeSolo');
|
|
879
|
+
} else if (popupOpen && touchScrolledRef.current) {
|
|
880
|
+
// The highlight is stale from a touch-scroll - close without selecting.
|
|
806
881
|
event.preventDefault();
|
|
882
|
+
// This happens on Enter, but re-using "escape" as the closest `AutocompleteCloseReason`
|
|
883
|
+
// to avoid creating a new reason
|
|
884
|
+
handleClose(event, 'escape');
|
|
807
885
|
}
|
|
808
|
-
|
|
886
|
+
break;
|
|
809
887
|
}
|
|
810
|
-
break;
|
|
811
888
|
case 'Escape':
|
|
812
889
|
if (popupOpen) {
|
|
813
890
|
// Avoid Opera to exit fullscreen mode.
|
|
@@ -893,7 +970,12 @@ function useAutocomplete(props) {
|
|
|
893
970
|
setFocused(false);
|
|
894
971
|
firstFocus.current = true;
|
|
895
972
|
ignoreFocus.current = false;
|
|
896
|
-
|
|
973
|
+
|
|
974
|
+
// Auto-select the highlighted option on blur, but only if the highlight
|
|
975
|
+
// came from keyboard navigation or was set programmatically (autoHighlight).
|
|
976
|
+
// Mouse hover and touch should not trigger selection — the user may have
|
|
977
|
+
// moved the pointer over an option without intending to commit to it.
|
|
978
|
+
if (autoSelect && highlightedIndexRef.current !== -1 && popupOpen && highlightReasonRef.current !== 'mouse' && highlightReasonRef.current !== 'touch') {
|
|
897
979
|
selectNewValue(event, filteredOptions[highlightedIndexRef.current], 'blur');
|
|
898
980
|
} else if (autoSelect && freeSolo && inputValue !== '') {
|
|
899
981
|
selectNewValue(event, inputValue, 'blur', 'freeSolo');
|
|
@@ -904,9 +986,10 @@ function useAutocomplete(props) {
|
|
|
904
986
|
};
|
|
905
987
|
const handleInputChange = event => {
|
|
906
988
|
const newValue = event.target.value;
|
|
907
|
-
|
|
989
|
+
const valueChanged = inputValue !== newValue;
|
|
990
|
+
if (valueChanged) {
|
|
908
991
|
setInputValueState(newValue);
|
|
909
|
-
|
|
992
|
+
touchScrolledRef.current = false;
|
|
910
993
|
if (onInputChange) {
|
|
911
994
|
onInputChange(event, newValue, 'input');
|
|
912
995
|
}
|
|
@@ -920,6 +1003,12 @@ function useAutocomplete(props) {
|
|
|
920
1003
|
} else {
|
|
921
1004
|
handleOpen(event);
|
|
922
1005
|
}
|
|
1006
|
+
|
|
1007
|
+
// Called after handleOpen so it overrides handleOpen's setInputPristine(true)
|
|
1008
|
+
// when the first keystroke also opens the popup.
|
|
1009
|
+
if (valueChanged) {
|
|
1010
|
+
setInputPristine(false);
|
|
1011
|
+
}
|
|
923
1012
|
};
|
|
924
1013
|
const handleOptionMouseMove = event => {
|
|
925
1014
|
const index = Number(event.currentTarget.getAttribute('data-option-index'));
|
|
@@ -929,20 +1018,35 @@ function useAutocomplete(props) {
|
|
|
929
1018
|
index,
|
|
930
1019
|
reason: 'mouse'
|
|
931
1020
|
});
|
|
1021
|
+
} else {
|
|
1022
|
+
// The option is already highlighted (e.g. programmatically via autoHighlight),
|
|
1023
|
+
// but the user moved the mouse over it — mark as mouse-initiated so
|
|
1024
|
+
// autoSelect on blur correctly treats this as incidental hover.
|
|
1025
|
+
highlightReasonRef.current = 'mouse';
|
|
1026
|
+
}
|
|
1027
|
+
// Don't clear the touch-scroll guard while touch state is still latched.
|
|
1028
|
+
// After a touch gesture, browsers may fire compatibility mousemove
|
|
1029
|
+
// events; if those cleared the guard immediately, later compat events in
|
|
1030
|
+
// the same sequence could be misclassified as a real mouse interaction.
|
|
1031
|
+
// Touch state is cleared by the next deliberate interaction
|
|
1032
|
+
// (keyboard nav, handleOptionClick, or handleOpen).
|
|
1033
|
+
if (!isTouchRef.current) {
|
|
1034
|
+
touchScrolledRef.current = false;
|
|
932
1035
|
}
|
|
933
1036
|
};
|
|
934
1037
|
const handleOptionTouchStart = event => {
|
|
1038
|
+
touchScrolledRef.current = false;
|
|
935
1039
|
setHighlightedIndex({
|
|
936
1040
|
event,
|
|
937
1041
|
index: Number(event.currentTarget.getAttribute('data-option-index')),
|
|
938
1042
|
reason: 'touch'
|
|
939
1043
|
});
|
|
940
|
-
|
|
1044
|
+
isTouchRef.current = true;
|
|
941
1045
|
};
|
|
942
1046
|
const handleOptionClick = event => {
|
|
943
1047
|
const index = Number(event.currentTarget.getAttribute('data-option-index'));
|
|
944
1048
|
selectNewValue(event, filteredOptions[index], 'selectOption');
|
|
945
|
-
|
|
1049
|
+
isTouchRef.current = false;
|
|
946
1050
|
};
|
|
947
1051
|
const handleItemDelete = index => event => {
|
|
948
1052
|
const newValue = value.slice();
|
|
@@ -967,11 +1071,11 @@ function useAutocomplete(props) {
|
|
|
967
1071
|
// Prevent input blur when interacting with the combobox
|
|
968
1072
|
const handleMouseDown = event => {
|
|
969
1073
|
// Prevent focusing the input if click is anywhere outside the Autocomplete
|
|
970
|
-
if (!event.currentTarget
|
|
1074
|
+
if (!(0, _contains.default)(event.currentTarget, event.target)) {
|
|
971
1075
|
return;
|
|
972
1076
|
}
|
|
973
1077
|
// Don't interfere with interactions outside the input area (e.g. helper text)
|
|
974
|
-
if (anchorEl && !
|
|
1078
|
+
if (anchorEl && !(0, _contains.default)(anchorEl, event.target)) {
|
|
975
1079
|
return;
|
|
976
1080
|
}
|
|
977
1081
|
if (event.target.getAttribute('id') !== id) {
|
|
@@ -982,11 +1086,11 @@ function useAutocomplete(props) {
|
|
|
982
1086
|
// Focus the input when interacting with the combobox
|
|
983
1087
|
const handleClick = event => {
|
|
984
1088
|
// Prevent focusing the input if click is anywhere outside the Autocomplete
|
|
985
|
-
if (!event.currentTarget
|
|
1089
|
+
if (!(0, _contains.default)(event.currentTarget, event.target)) {
|
|
986
1090
|
return;
|
|
987
1091
|
}
|
|
988
1092
|
// Don't interfere with interactions outside the input area (e.g. helper text)
|
|
989
|
-
if (anchorEl && !
|
|
1093
|
+
if (anchorEl && !(0, _contains.default)(anchorEl, event.target)) {
|
|
990
1094
|
return;
|
|
991
1095
|
}
|
|
992
1096
|
inputRef.current.focus();
|
|
@@ -1111,6 +1215,11 @@ function useAutocomplete(props) {
|
|
|
1111
1215
|
onMouseDown: event => {
|
|
1112
1216
|
// Prevent blur
|
|
1113
1217
|
event.preventDefault();
|
|
1218
|
+
},
|
|
1219
|
+
onScroll: () => {
|
|
1220
|
+
if (isTouchRef.current) {
|
|
1221
|
+
touchScrolledRef.current = true;
|
|
1222
|
+
}
|
|
1114
1223
|
}
|
|
1115
1224
|
}),
|
|
1116
1225
|
getOptionProps: ({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _contains = _interopRequireDefault(require("@mui/utils/contains"));
|
|
9
|
+
var _default = exports.default = _contains.default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const FOCUSABLE_ATTRIBUTE = "data-mui-focusable";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the element marked as the initial focus target inside a focus trap.
|
|
4
|
+
* The root element takes precedence over marked descendants so components can
|
|
5
|
+
* opt into focusing their own root surface directly.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getFocusTarget(rootElement: HTMLElement | null | undefined): HTMLElement | null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.FOCUSABLE_ATTRIBUTE = void 0;
|
|
7
|
+
exports.getFocusTarget = getFocusTarget;
|
|
8
|
+
const FOCUSABLE_ATTRIBUTE = exports.FOCUSABLE_ATTRIBUTE = 'data-mui-focusable';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns the element marked as the initial focus target inside a focus trap.
|
|
12
|
+
* The root element takes precedence over marked descendants so components can
|
|
13
|
+
* opt into focusing their own root surface directly.
|
|
14
|
+
*/
|
|
15
|
+
function getFocusTarget(rootElement) {
|
|
16
|
+
if (!rootElement) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return rootElement.hasAttribute(FOCUSABLE_ATTRIBUTE) ? rootElement : rootElement.querySelector(`[${FOCUSABLE_ATTRIBUTE}]`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _getEventTarget = _interopRequireDefault(require("@mui/utils/getEventTarget"));
|
|
9
|
+
var _default = exports.default = _getEventTarget.default;
|
package/version/index.js
CHANGED
|
@@ -4,9 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.version = exports.prerelease = exports.patch = exports.minor = exports.major = exports.default = void 0;
|
|
7
|
-
const version = exports.version = "7.3.
|
|
7
|
+
const version = exports.version = "7.3.11";
|
|
8
8
|
const major = exports.major = Number("7");
|
|
9
9
|
const minor = exports.minor = Number("3");
|
|
10
|
-
const patch = exports.patch = Number("
|
|
10
|
+
const patch = exports.patch = Number("11");
|
|
11
11
|
const prerelease = exports.prerelease = undefined;
|
|
12
12
|
var _default = exports.default = version;
|