UNPKG

@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

132 lines • 8.88 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { useImperativeHandle, useRef } from 'react'; import clsx from 'clsx'; import { useUniqueId, warnOnce } from '@awsui/component-toolkit/internal'; import { useFormFieldContext } from '../contexts/form-field'; import { useInternalI18n } from '../i18n/context'; import AutosuggestInput from '../internal/components/autosuggest-input'; import DropdownFooter from '../internal/components/dropdown-footer'; import { useDropdownStatus } from '../internal/components/dropdown-status'; import { fireCancelableEvent, fireNonCancelableEvent, } from '../internal/events'; import checkControlled from '../internal/hooks/check-controlled'; import { checkOptionValueField } from '../select/utils/check-option-value-field'; import { useAutosuggestLoadMore } from './load-more-controller'; import { useAutosuggestItems } from './options-controller'; import AutosuggestOptionsList from './options-list'; import styles from './styles.css.js'; const InternalAutosuggest = React.forwardRef((props, ref) => { var _a, _b; const { value, onChange, onBlur, onFocus, onKeyUp, onLoadItems, options, filteringType = 'auto', statusType = 'finished', placeholder, clearAriaLabel, name, disabled, disableBrowserAutocorrect = false, autoFocus, readOnly, ariaLabel, ariaRequired, enteredTextLabel, hideEnteredTextOption, filteringResultsText, onKeyDown, virtualScroll, expandToViewport, onSelect, renderHighlightedAriaLive, style, __internalRootRef, ...restProps } = props; checkControlled('Autosuggest', 'value', value, 'onChange', onChange); checkOptionValueField('Autosuggest', 'options', options); const autosuggestInputRef = useRef(null); useImperativeHandle(ref, () => ({ focus: () => { var _a; return (_a = autosuggestInputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, select: () => { var _a; return (_a = autosuggestInputRef.current) === null || _a === void 0 ? void 0 : _a.select(); }, }), []); const i18n = useInternalI18n('autosuggest'); const errorIconAriaLabel = i18n('errorIconAriaLabel', restProps.errorIconAriaLabel); const selectedAriaLabel = i18n('selectedAriaLabel', restProps.selectedAriaLabel); const recoveryText = i18n('recoveryText', restProps.recoveryText); if (restProps.recoveryText && !onLoadItems) { warnOnce('Autosuggest', '`onLoadItems` must be provided for `recoveryText` to be displayed.'); } const [autosuggestItemsState, autosuggestItemsHandlers] = useAutosuggestItems({ options: options || [], filterValue: value, filterText: value, filteringType, enteredTextLabel, hideEnteredTextLabel: hideEnteredTextOption, onSelectItem: (option) => { var _a; const value = option.value || ''; fireNonCancelableEvent(onChange, { value }); fireNonCancelableEvent(onSelect, { value, selectedOption: option.type !== 'use-entered' ? option.option : undefined, }); (_a = autosuggestInputRef.current) === null || _a === void 0 ? void 0 : _a.close(); }, }); const autosuggestLoadMoreHandlers = useAutosuggestLoadMore({ options, statusType, onLoadItems: (detail) => fireNonCancelableEvent(onLoadItems, detail), }); const handleChange = (event) => { autosuggestItemsHandlers.setShowAll(false); autosuggestItemsHandlers.resetHighlightWithKeyboard(); fireNonCancelableEvent(onChange, event.detail); }; const handleDelayedInput = (event) => { autosuggestLoadMoreHandlers.fireLoadMoreOnInputChange(event.detail.value); }; const handleBlur = () => { fireNonCancelableEvent(onBlur, null); }; const handleFocus = () => { autosuggestItemsHandlers.setShowAll(true); autosuggestLoadMoreHandlers.fireLoadMoreOnInputFocus(); fireNonCancelableEvent(onFocus, null); }; const handleKeyUp = (event) => { fireCancelableEvent(onKeyUp, event.detail, event); }; const handleKeyDown = (event) => { fireCancelableEvent(onKeyDown, event.detail, event); }; const handlePressArrowDown = () => { if (autosuggestItemsState.items.length - 1 === autosuggestItemsState.highlightedIndex) { autosuggestItemsHandlers.goHomeWithKeyboard(); return; } autosuggestItemsHandlers.moveHighlightWithKeyboard(1); }; const handlePressArrowUp = () => { var _a; if ((((_a = autosuggestItemsState.highlightedOption) === null || _a === void 0 ? void 0 : _a.type) === 'child' && autosuggestItemsState.highlightedIndex === 1) || autosuggestItemsState.highlightedIndex === 0) { autosuggestItemsHandlers.goEndWithKeyboard(); return; } autosuggestItemsHandlers.moveHighlightWithKeyboard(-1); }; const handlePressEnter = () => { return autosuggestItemsHandlers.selectHighlightedOptionWithKeyboard(); }; const handleCloseDropdown = () => { autosuggestItemsHandlers.resetHighlightWithKeyboard(); }; const handleRecoveryClick = () => { var _a; autosuggestLoadMoreHandlers.fireLoadMoreOnRecoveryClick(); (_a = autosuggestInputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }; const formFieldContext = useFormFieldContext(restProps); const selfControlId = useUniqueId('input'); const footerControlId = useUniqueId('footer'); const controlId = (_a = formFieldContext.controlId) !== null && _a !== void 0 ? _a : selfControlId; const listId = useUniqueId('list'); const highlightedOptionIdSource = useUniqueId(); const highlightedOptionId = autosuggestItemsState.highlightedOption ? highlightedOptionIdSource : undefined; const isEmpty = !value && !autosuggestItemsState.items.length; const isFiltered = !!value && value.length !== 0 && !(filteringType === 'auto' && autosuggestItemsState.showAll); const filteredText = isFiltered ? filteringResultsText === null || filteringResultsText === void 0 ? void 0 : filteringResultsText(autosuggestItemsState.items.length, (_b = options === null || options === void 0 ? void 0 : options.length) !== null && _b !== void 0 ? _b : 0) : undefined; const dropdownStatus = useDropdownStatus({ ...props, isEmpty, recoveryText, errorIconAriaLabel, onRecoveryClick: handleRecoveryClick, filteringResultsText: filteredText, hasRecoveryCallback: !!onLoadItems, }); const shouldRenderDropdownContent = autosuggestItemsState.items.length !== 0 || !!dropdownStatus.content || (!hideEnteredTextOption && !!value); return (React.createElement(AutosuggestInput, { ...restProps, className: clsx(styles.root, restProps.className), ref: autosuggestInputRef, __internalRootRef: __internalRootRef, value: value, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyUp: handleKeyUp, onKeyDown: handleKeyDown, name: name, controlId: controlId, placeholder: placeholder, disabled: disabled, readOnly: readOnly, autoFocus: autoFocus, ariaLabel: ariaLabel, ariaRequired: ariaRequired, clearAriaLabel: clearAriaLabel, disableBrowserAutocorrect: disableBrowserAutocorrect, expandToViewport: expandToViewport, ariaControls: listId, ariaActivedescendant: highlightedOptionId, dropdownExpanded: shouldRenderDropdownContent, style: style, dropdownContent: shouldRenderDropdownContent && (React.createElement(AutosuggestOptionsList, { statusType: statusType, autosuggestItemsState: autosuggestItemsState, autosuggestItemsHandlers: autosuggestItemsHandlers, highlightedOptionId: highlightedOptionId, highlightText: value, listId: listId, controlId: controlId, handleLoadMore: autosuggestLoadMoreHandlers.fireLoadMoreOnScroll, hasDropdownStatus: dropdownStatus.content !== null, virtualScroll: virtualScroll, selectedAriaLabel: selectedAriaLabel, renderHighlightedAriaLive: renderHighlightedAriaLive, listBottom: !dropdownStatus.isSticky ? React.createElement(DropdownFooter, { content: dropdownStatus.content, id: footerControlId }) : null, ariaDescribedby: dropdownStatus.content ? footerControlId : undefined })), dropdownFooter: dropdownStatus.isSticky && dropdownStatus.content ? (React.createElement(DropdownFooter, { id: footerControlId, content: dropdownStatus.content, hasItems: autosuggestItemsState.items.length >= 1 })) : null, loopFocus: dropdownStatus.hasRecoveryButton, onCloseDropdown: handleCloseDropdown, onDelayedInput: handleDelayedInput, onPressArrowDown: handlePressArrowDown, onPressArrowUp: handlePressArrowUp, onPressEnter: handlePressEnter })); }); export default InternalAutosuggest; //# sourceMappingURL=internal.js.map