@awsui/components-react
Version:
On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en
107 lines • 5.07 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { __rest } from "tslib";
import { useMemo, useState } from 'react';
import { warnOnce } from '@awsui/component-toolkit/internal';
import { useInternalI18n } from '../i18n/context';
import { generateTestIndexes } from '../internal/components/options-list/utils/test-indexes';
import { useHighlightedOption, } from '../internal/components/options-list/utils/use-highlight-option';
import { filterOptions } from './utils/utils';
const isHighlightable = (option) => {
return !!option && option.type !== 'parent';
};
const isInteractive = (option) => !!option && !option.disabled && option.type !== 'parent';
export const useAutosuggestItems = ({ options, filterValue, filterText, filteringType, enteredTextLabel, hideEnteredTextLabel, onSelectItem, }) => {
const i18n = useInternalI18n('autosuggest');
const [showAll, setShowAll] = useState(false);
const { items, getItemGroup, getItemParent } = useMemo(() => createItems(options), [options]);
const enteredItemLabel = i18n('enteredTextLabel', enteredTextLabel === null || enteredTextLabel === void 0 ? void 0 : enteredTextLabel(filterValue), format => format({ value: filterValue }));
if (!enteredItemLabel) {
warnOnce('Autosuggest', 'A value for enteredTextLabel must be provided.');
}
const filteredItems = useMemo(() => {
const filteredItems = filteringType === 'auto' && !showAll ? filterOptions(items, filterText) : [...items];
if (filterValue && !hideEnteredTextLabel) {
filteredItems.unshift({
value: filterValue,
type: 'use-entered',
label: enteredItemLabel,
option: { value: filterValue },
});
}
generateTestIndexes(filteredItems, getItemParent);
return filteredItems;
}, [filteringType, showAll, items, filterText, filterValue, hideEnteredTextLabel, getItemParent, enteredItemLabel]);
const [highlightedOptionState, highlightedOptionHandlers] = useHighlightedOption({
options: filteredItems,
isHighlightable,
});
const selectHighlightedOptionWithKeyboard = () => {
var _a;
if (highlightedOptionState.highlightedOption && !isInteractive(highlightedOptionState.highlightedOption)) {
// skip selection when a non-interactive item is active
return false;
}
onSelectItem((_a = highlightedOptionState.highlightedOption) !== null && _a !== void 0 ? _a : {
// put use-entered item as a fallback
value: filterValue,
type: 'use-entered',
option: { value: filterValue },
});
return true;
};
const highlightVisibleOptionWithMouse = (index) => {
if (filteredItems[index] && isHighlightable(filteredItems[index])) {
highlightedOptionHandlers.setHighlightedIndexWithMouse(index);
}
};
const selectVisibleOptionWithMouse = (index) => {
if (filteredItems[index] && isInteractive(filteredItems[index])) {
onSelectItem(filteredItems[index]);
}
};
return [
Object.assign(Object.assign({}, highlightedOptionState), { items: filteredItems, showAll, getItemGroup }),
Object.assign(Object.assign({}, highlightedOptionHandlers), { setShowAll,
selectHighlightedOptionWithKeyboard,
highlightVisibleOptionWithMouse,
selectVisibleOptionWithMouse }),
];
};
function createItems(options) {
const items = [];
const itemToGroup = new WeakMap();
const getItemParent = (item) => itemToGroup.get(item);
const getItemGroup = (item) => { var _a; return (_a = getItemParent(item)) === null || _a === void 0 ? void 0 : _a.option; };
for (const option of options) {
if (isGroup(option)) {
for (const item of flattenGroup(option)) {
items.push(item);
}
}
else {
items.push(Object.assign(Object.assign({}, option), { option }));
}
}
function flattenGroup(group) {
const { options } = group, rest = __rest(group, ["options"]);
let hasOnlyDisabledChildren = true;
const groupItem = Object.assign(Object.assign({}, rest), { type: 'parent', option: group });
const items = [groupItem];
for (const option of options) {
if (!option.disabled) {
hasOnlyDisabledChildren = false;
}
const childOption = Object.assign(Object.assign({}, option), { type: 'child', disabled: option.disabled || rest.disabled, option });
items.push(childOption);
itemToGroup.set(childOption, groupItem);
}
items[0].disabled = items[0].disabled || hasOnlyDisabledChildren;
return items;
}
return { items, getItemGroup, getItemParent };
}
function isGroup(optionOrGroup) {
return 'options' in optionOrGroup;
}
//# sourceMappingURL=options-controller.js.map