UNPKG

native-base

Version:

Essential cross-platform UI components for React Native

220 lines (183 loc) 6.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Typeahead = void 0; var _react = _interopRequireDefault(require("react")); var _button = require("@react-native-aria/button"); var _combobox = require("@react-stately/combobox"); var _combobox2 = require("@react-native-aria/combobox"); var _listbox = require("@react-native-aria/listbox"); var _reactNative = require("react-native"); var _collections = require("@react-stately/collections"); var _Box = _interopRequireDefault(require("../../primitives/Box")); var _Pressable = require("../../primitives/Pressable"); var _Text = _interopRequireDefault(require("../../primitives/Text")); var _tools = require("../../../theme/tools"); var _types = require("./types"); var _Input = require("../../primitives/Input"); var _hooks = require("../../../hooks"); var _useHasResponsiveProps = require("../../../hooks/useHasResponsiveProps"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } const Typeahead = /*#__PURE__*/_react.default.forwardRef(({ onSelectedItemChange, options, renderItem, getOptionLabel, getOptionKey, onChange, numberOfItems, ...rest }, ref) => { //TODO: refactor for responsive prop if ((0, _useHasResponsiveProps.useHasResponsiveProps)(rest)) { return null; } return /*#__PURE__*/_react.default.createElement(ComboBoxImplementation, _extends({}, rest, { onSelectionChange: onSelectedItemChange, items: numberOfItems !== undefined ? options.slice(0, numberOfItems) : options, onInputChange: onChange, ref: ref }), item => { if (typeof item !== 'string' && getOptionLabel === undefined) { throw new Error('Please use getOptionLabel prop'); } if (item.id === undefined && getOptionKey === undefined) { throw new Error('Please use getOptionKey prop'); } const optionLabel = getOptionLabel ? getOptionLabel(item) : item; const optionKey = getOptionKey ? getOptionKey(item) : item.id !== undefined ? item.id : optionLabel; return /*#__PURE__*/_react.default.createElement(_collections.Item, { textValue: optionLabel, key: optionKey }, renderItem ? renderItem(item) : /*#__PURE__*/_react.default.createElement(_Box.default, { p: 2, justifyContent: "center" }, /*#__PURE__*/_react.default.createElement(_Text.default, null, optionLabel))); }); }); exports.Typeahead = Typeahead; const ComboBoxImplementation = /*#__PURE__*/_react.default.forwardRef((props, ref) => { const [layoutProps] = (0, _tools.extractInObject)(props, _types.layoutPropsList); let state = (0, _combobox.useComboBoxState)(props); let triggerRef = _react.default.useRef(null); let inputRef = _react.default.useRef(null); let listBoxRef = _react.default.useRef(null); let popoverRef = _react.default.useRef(null); let { buttonProps: triggerProps, inputProps, listBoxProps, labelProps } = (0, _combobox2.useComboBox)({ ...props, inputRef, buttonRef: triggerRef, listBoxRef, popoverRef, menuTrigger: 'input' }, state); const toggleIconSetter = () => { if (typeof props.toggleIcon === 'function') return props.toggleIcon({ isOpen: state.isOpen }); return props.toggleIcon; }; let { buttonProps } = (0, _button.useButton)(triggerProps); return /*#__PURE__*/_react.default.createElement(_Box.default, _extends({ flexDirection: "row" }, layoutProps, { ref: ref }), /*#__PURE__*/_react.default.createElement(_Box.default, { flex: 1 }, props.label && /*#__PURE__*/_react.default.createElement(_Text.default, _extends({}, labelProps, { pb: 1 }), props.label), /*#__PURE__*/_react.default.createElement(_Input.Input, _extends({}, inputProps, { ref: inputRef, InputRightElement: /*#__PURE__*/ // @ts-ignore - RN has hitSlop type inconsistent for View and Pressable! _react.default.createElement(_Pressable.Pressable, _extends({}, buttonProps, { ref: triggerRef }), toggleIconSetter()) })), state.isOpen && /*#__PURE__*/_react.default.createElement(ListBoxPopup, _extends({}, listBoxProps, { listBoxRef: listBoxRef, popoverRef: popoverRef, state: state, label: props.label })))); }); function ListBoxPopup(props) { let { popoverRef, listBoxRef, state, dropdownHeight, label } = props; let { listBoxProps } = (0, _listbox.useListBox)({ label, autoFocus: state.focusStrategy, disallowEmptySelection: true }, state, listBoxRef); return /*#__PURE__*/_react.default.createElement(_Box.default, { ref: popoverRef }, /*#__PURE__*/_react.default.createElement(_Box.default, { position: "absolute", width: "100%", maxHeight: dropdownHeight !== null && dropdownHeight !== void 0 ? dropdownHeight : 200 }, /*#__PURE__*/_react.default.createElement(_reactNative.ScrollView, _extends({}, listBoxProps, { keyboardShouldPersistTaps: "handled", ref: node => { if (_reactNative.Platform.OS === 'web') { listBoxRef.current = (0, _reactNative.findNodeHandle)(node); } else { listBoxRef.current = node; } } }), [...state.collection].map(item => /*#__PURE__*/_react.default.createElement(Option, { key: item.key, item: item, state: state }))))); } function Option({ item, state }) { const searchItemStyle = (0, _hooks.useThemeProps)('TypeAheadSearchItem', {}); let ref = _react.default.useRef(null); let isDisabled = state.disabledKeys.has(item.key); let isSelected = state.selectionManager.isSelected(item.key); let isFocused = state.selectionManager.focusedKey === item.key; let { optionProps } = (0, _listbox.useOption)({ key: item.key, isDisabled, isSelected, shouldFocusOnHover: true, shouldUseVirtualFocus: true }, state, ref); let backgroundColor = searchItemStyle.backgroundColor; let opacity = 1; if (isSelected) { backgroundColor = searchItemStyle._focus.backgroundColor; } else if (isFocused) { backgroundColor = searchItemStyle._focus.backgroundColor; } else if (isDisabled) { opacity = 0.6; backgroundColor = searchItemStyle._disabled.backgroundColor; } return /*#__PURE__*/_react.default.createElement(_Pressable.Pressable, _extends({}, optionProps, { opacity: opacity, cursor: isDisabled ? _reactNative.Platform.OS === 'web' ? 'not-allowed' : null : null, backgroundColor: backgroundColor, ref: ref }), item.rendered); } //# sourceMappingURL=Typeahead.js.map