Outlook_Addin_LLM/node_modules/@fluentui/react-combobox/lib-commonjs/utils/useComboboxBaseState.js

202 lines
7.9 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useComboboxBaseState", {
enumerable: true,
get: function() {
return useComboboxBaseState;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactdom = /*#__PURE__*/ _interop_require_wildcard._(require("react-dom"));
const _reactutilities = require("@fluentui/react-utilities");
const _useOptionCollection = require("../utils/useOptionCollection");
const _useSelection = require("../utils/useSelection");
const useComboboxBaseState = (props)=>{
'use no memo';
const { appearance = 'outline', disableAutoFocus, children, clearable = false, editable = false, inlinePopup = false, mountNode = undefined, multiselect, onOpenChange, size = 'medium', activeDescendantController, freeform = false, disabled = false, onActiveOptionChange = null } = props;
const optionCollection = (0, _useOptionCollection.useOptionCollection)();
const { getOptionsMatchingValue } = optionCollection;
const { getOptionById } = optionCollection;
const getActiveOption = _react.useCallback(()=>{
const activeOptionId = activeDescendantController.active();
return activeOptionId ? getOptionById(activeOptionId) : undefined;
}, [
activeDescendantController,
getOptionById
]);
// Keeping some kind of backwards compatible functionality here
// eslint-disable-next-line @typescript-eslint/naming-convention
const UNSAFE_activeOption = getActiveOption();
// eslint-disable-next-line @typescript-eslint/naming-convention
const UNSAFE_setActiveOption = _react.useCallback((option)=>{
let nextOption = undefined;
if (typeof option === 'function') {
const activeOption = getActiveOption();
nextOption = option(activeOption);
}
if (nextOption) {
activeDescendantController.focus(nextOption.id);
} else {
activeDescendantController.blur();
}
}, [
activeDescendantController,
getActiveOption
]);
// track whether keyboard focus outline should be shown
// tabster/keyborg doesn't work here, since the actual keyboard focus target doesn't move
const [focusVisible, setFocusVisible] = _react.useState(false);
// track focused state to conditionally render collapsed listbox
// when the trigger is focused - the listbox should but hidden until the open state is changed
const [hasFocus, setHasFocus] = _react.useState(false);
const ignoreNextBlur = _react.useRef(false);
// calculate value based on props, internal value changes, and selected options
const isFirstMount = (0, _reactutilities.useFirstMount)();
const [controllableValue, setValue] = (0, _reactutilities.useControllableState)({
state: props.value,
initialState: undefined
});
const { selectedOptions, selectOption: baseSelectOption, clearSelection } = (0, _useSelection.useSelection)(props);
// reset any typed value when an option is selected
const selectOption = _react.useCallback((ev, option)=>{
_reactdom.unstable_batchedUpdates(()=>{
setValue(undefined);
baseSelectOption(ev, option);
});
}, [
setValue,
baseSelectOption
]);
const value = _react.useMemo(()=>{
// don't compute the value if it is defined through props or setValue,
if (controllableValue !== undefined) {
return controllableValue;
}
// handle defaultValue here, so it is overridden by selection
if (isFirstMount && props.defaultValue !== undefined) {
return props.defaultValue;
}
const selectedOptionsText = getOptionsMatchingValue((optionValue)=>{
return selectedOptions.includes(optionValue);
}).map((option)=>option.text);
if (multiselect) {
// editable inputs should not display multiple selected options in the input as text
return editable ? '' : selectedOptionsText.join(', ');
}
return selectedOptionsText[0];
// do not change value after isFirstMount changes,
// we do not want to accidentally override defaultValue on a second render
// unless another value is intentionally set
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
controllableValue,
editable,
getOptionsMatchingValue,
multiselect,
props.defaultValue,
selectedOptions
]);
// Handle open state, which is shared with options in context
const [open, setOpenState] = (0, _reactutilities.useControllableState)({
state: props.open,
defaultState: props.defaultOpen,
initialState: false
});
const setOpen = _react.useCallback((event, newState)=>{
if (disabled) {
return;
}
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(event, {
open: newState
});
_reactdom.unstable_batchedUpdates(()=>{
if (!newState && !freeform) {
setValue(undefined);
}
setOpenState(newState);
});
}, [
onOpenChange,
setOpenState,
setValue,
freeform,
disabled
]);
// update active option based on change in open state
_react.useEffect(()=>{
if (open) {
// if it is single-select and there is a selected option, start at the selected option
if (!multiselect && selectedOptions.length > 0) {
const selectedOption = getOptionsMatchingValue((v)=>v === selectedOptions[0]).pop();
if (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.id) {
activeDescendantController.focus(selectedOption.id);
}
}
} else {
activeDescendantController.blur();
}
// this should only be run in response to changes in the open state
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
open,
activeDescendantController
]);
// Fallback focus when children are updated in an open popover results in no item being focused
_react.useEffect(()=>{
if (open && !disableAutoFocus && !activeDescendantController.active()) {
activeDescendantController.first();
}
// this should only be run in response to changes in the open state or children
}, [
open,
children,
disableAutoFocus,
activeDescendantController,
getOptionById
]);
const onActiveDescendantChange = (0, _reactutilities.useEventCallback)((event)=>{
const previousOption = event.detail.previousId ? optionCollection.getOptionById(event.detail.previousId) : null;
const nextOption = optionCollection.getOptionById(event.detail.id);
onActiveOptionChange === null || onActiveOptionChange === void 0 ? void 0 : onActiveOptionChange(event, {
event,
type: 'change',
previousOption,
nextOption
});
});
return {
...optionCollection,
freeform,
disabled,
selectOption,
clearSelection,
selectedOptions,
activeOption: UNSAFE_activeOption,
appearance,
clearable,
focusVisible,
ignoreNextBlur,
inlinePopup,
mountNode,
open,
hasFocus,
setActiveOption: UNSAFE_setActiveOption,
setFocusVisible,
setHasFocus,
setOpen,
setValue,
size,
value,
multiselect,
onOptionClick: (0, _reactutilities.useEventCallback)((e)=>{
if (!multiselect) {
setOpen(e, false);
}
}),
onActiveDescendantChange
};
};