Private
Public Access
1
0
Files
power-apps-codeapps-blog-part2/node_modules/@fluentui/react-combobox/lib-commonjs/components/Dropdown/useButtonTriggerSlot.js

101 lines
3.8 KiB
JavaScript

'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useButtonTriggerSlot", {
enumerable: true,
get: function() {
return useButtonTriggerSlot;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactutilities = require("@fluentui/react-utilities");
const _useTriggerSlot = require("../../utils/useTriggerSlot");
const _dropdownKeyActions = require("../../utils/dropdownKeyActions");
function useButtonTriggerSlot(triggerFromProps, ref, options) {
'use no memo';
const { state: { open, setOpen, getOptionById }, defaultProps, activeDescendantController } = options;
// jump to matching option based on typing
const searchString = _react.useRef('');
const [setKeyTimeout, clearKeyTimeout] = (0, _reactutilities.useTimeout)();
const moveToNextMatchingOption = (matcher, opt = {
startFromNext: false
})=>{
const { startFromNext } = opt;
const activeOptionId = activeDescendantController.active();
const nextInOrder = activeDescendantController.find((id)=>{
const option = getOptionById(id);
return !!option && matcher(option.text);
}, {
startFrom: startFromNext ? activeDescendantController.next({
passive: true
}) : activeOptionId
});
if (nextInOrder) {
return nextInOrder;
}
// Cycle back to first match
return activeDescendantController.find((id)=>{
const option = getOptionById(id);
return !!option && matcher(option.text);
});
};
const moveToNextMatchingOptionWithSameCharacterHandling = ()=>{
if (moveToNextMatchingOption((optionText)=>{
return optionText.toLocaleLowerCase().indexOf(searchString.current) === 0;
}, {
// Slowly pressing the same key will cycle through options
startFromNext: searchString.current.length === 1
})) {
return;
}
// if there are no direct matches, check if the search is all the same letter, e.g. "aaa"
if (allCharactersSame(searchString.current) && moveToNextMatchingOption((optionText)=>{
return optionText.toLocaleLowerCase().indexOf(searchString.current[0]) === 0;
}, {
// if the search is all the same letter, cycle through options starting with that letter
startFromNext: true
})) {
return;
}
activeDescendantController.blur();
};
const onTriggerKeyDown = (ev)=>{
// clear timeout, if it exists
clearKeyTimeout();
// if the key was a char key, update search string
if ((0, _dropdownKeyActions.getDropdownActionFromKey)(ev) === 'Type') {
// update search string
searchString.current += ev.key.toLowerCase();
setKeyTimeout(()=>{
searchString.current = '';
}, 500);
if (open) {
moveToNextMatchingOptionWithSameCharacterHandling();
}
// update state
!open && setOpen(ev, true);
}
};
const trigger = (0, _useTriggerSlot.useTriggerSlot)(triggerFromProps, ref, {
state: options.state,
defaultProps,
elementType: 'button',
activeDescendantController
});
trigger.onKeyDown = (0, _reactutilities.mergeCallbacks)(onTriggerKeyDown, trigger.onKeyDown);
return trigger;
}
/**
* @returns - whether every character in the string is the same
*/ function allCharactersSame(str) {
for(let i = 1; i < str.length; i++){
if (str[i] !== str[i - 1]) {
return false;
}
}
return true;
}